{
 "metadata": {
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3",
   "language": "python"
  },
  "language_info": {
   "name": "python",
   "version": "3.10.13",
   "mimetype": "text/x-python",
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "pygments_lexer": "ipython3",
   "nbconvert_exporter": "python",
   "file_extension": ".py"
  },
  "kaggle": {
   "accelerator": "nvidiaTeslaT4",
   "dataSources": [],
   "isInternetEnabled": true,
   "language": "python",
   "sourceType": "notebook",
   "isGpuEnabled": true
  }
 },
 "nbformat_minor": 4,
 "nbformat": 4,
 "cells": [
  {
   "cell_type": "code",
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n",
    "seed = 42\n",
    "torch.manual_seed(seed)\n",
    "torch.cuda.manual_seed_all(seed)\n"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:31:44.936725Z",
     "start_time": "2024-05-02T08:31:40.034353600Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:12.527334Z",
     "iopub.execute_input": "2024-05-03T04:47:12.527802Z",
     "iopub.status.idle": "2024-05-03T04:47:17.362854Z",
     "shell.execute_reply.started": "2024-05-03T04:47:12.527757Z",
     "shell.execute_reply": "2024-05-03T04:47:17.361864Z"
    },
    "trusted": true
   },
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "text": "sys.version_info(major=3, minor=10, micro=13, releaselevel='final', serial=0)\nmatplotlib 3.7.5\nnumpy 1.26.4\npandas 2.2.2\nsklearn 1.2.2\ntorch 2.1.2\ncuda:0\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 准备数据"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "from tensorflow import keras\n",
    "#用karas有的数据集imdb，电影分类,分电影是积极的，还是消极的\n",
    "imdb = keras.datasets.imdb\n",
    "#载入数据使用下面两个参数\n",
    "vocab_size = 10000  #词典大小，仅保留训练数据中前10000个最经常出现的单词，低频单词被舍弃\n",
    "index_from = 3  #0,1,2,3空出来做别的事\n",
    "#前一万个词出现词频最高的会保留下来进行处理，后面的作为特殊字符处理，\n",
    "# 小于3的id都是特殊字符，下面代码有写\n",
    "# 需要注意的一点是取出来的词表还是从1开始的，需要做处理\n",
    "(train_data, train_labels), (test_data, test_labels) = imdb.load_data(\n",
    "    num_words = vocab_size, index_from = index_from)"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:04.220762800Z",
     "start_time": "2024-05-02T08:31:48.083348400Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:17.364755Z",
     "iopub.execute_input": "2024-05-03T04:47:17.365247Z",
     "iopub.status.idle": "2024-05-03T04:47:34.391998Z",
     "shell.execute_reply.started": "2024-05-03T04:47:17.365218Z",
     "shell.execute_reply": "2024-05-03T04:47:34.391210Z"
    },
    "trusted": true
   },
   "execution_count": 2,
   "outputs": [
    {
     "name": "stderr",
     "text": "2024-05-03 04:47:19.154174: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n2024-05-03 04:47:19.154307: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n2024-05-03 04:47:19.280829: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
     "output_type": "stream"
    },
    {
     "name": "stdout",
     "text": "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz\n\u001B[1m17464789/17464789\u001B[0m \u001B[32m━━━━━━━━━━━━━━━━━━━━\u001B[0m\u001B[37m\u001B[0m \u001B[1m0s\u001B[0m 0us/step\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "\n",
    "print(\"train\", len(train_data), train_labels.shape)  #25000个样本，每个样本是一段话，每个单词用一个数字表示\n",
    "print(\"test\", len(test_data), test_labels.shape)"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:14.425129500Z",
     "start_time": "2024-05-02T08:32:14.402142900Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:34.393563Z",
     "iopub.execute_input": "2024-05-03T04:47:34.394093Z",
     "iopub.status.idle": "2024-05-03T04:47:34.399413Z",
     "shell.execute_reply.started": "2024-05-03T04:47:34.394068Z",
     "shell.execute_reply": "2024-05-03T04:47:34.398409Z"
    },
    "trusted": true
   },
   "execution_count": 3,
   "outputs": [
    {
     "name": "stdout",
     "text": "train 25000 (25000,)\ntest 25000 (25000,)\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "#载入词表，看下词表长度，词表就像英语字典\n",
    "word_index = imdb.get_word_index()\n",
    "print(len(word_index))\n",
    "print(type(word_index))\n",
    "#词表虽然有8万多，但是我们只载入了最高频的1万词！！！！"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:17.066012200Z",
     "start_time": "2024-05-02T08:32:16.837139900Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:34.402571Z",
     "iopub.execute_input": "2024-05-03T04:47:34.403158Z",
     "iopub.status.idle": "2024-05-03T04:47:34.535124Z",
     "shell.execute_reply.started": "2024-05-03T04:47:34.403131Z",
     "shell.execute_reply": "2024-05-03T04:47:34.534127Z"
    },
    "trusted": true
   },
   "execution_count": 4,
   "outputs": [
    {
     "name": "stdout",
     "text": "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb_word_index.json\n\u001B[1m1641221/1641221\u001B[0m \u001B[32m━━━━━━━━━━━━━━━━━━━━\u001B[0m\u001B[37m\u001B[0m \u001B[1m0s\u001B[0m 0us/step\n88584\n<class 'dict'>\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 构造 word2idx 和 idx2word"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "word2idx = {word: idx + 3 for word, idx in word_index.items()}\n",
    "word2idx.update({\n",
    "    \"[PAD]\": 0,     # 填充 token\n",
    "    \"[BOS]\": 1,     # begin of sentence\n",
    "    \"[UNK]\": 2,     # 未知 token\n",
    "    \"[EOS]\": 3,     # end of sentence\n",
    "})\n",
    "\n",
    "idx2word = {idx: word for word, idx in word2idx.items()}"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:20.506027300Z",
     "start_time": "2024-05-02T08:32:20.420076700Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:34.536374Z",
     "iopub.execute_input": "2024-05-03T04:47:34.536752Z",
     "iopub.status.idle": "2024-05-03T04:47:34.579550Z",
     "shell.execute_reply.started": "2024-05-03T04:47:34.536716Z",
     "shell.execute_reply": "2024-05-03T04:47:34.578607Z"
    },
    "trusted": true
   },
   "execution_count": 5,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "# 选择 max_length\n",
    "length_collect = {}\n",
    "for text in train_data:\n",
    "    length = len(text)\n",
    "    length_collect[length] = length_collect.get(length, 0) + 1\n",
    "    \n",
    "MAX_LENGTH = 500\n",
    "plt.bar(length_collect.keys(), length_collect.values())\n",
    "plt.axvline(MAX_LENGTH, label=\"max length\", c=\"gray\", ls=\":\")\n",
    "plt.legend()\n",
    "plt.show()"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:34.580697Z",
     "iopub.execute_input": "2024-05-03T04:47:34.581037Z",
     "iopub.status.idle": "2024-05-03T04:47:36.765733Z",
     "shell.execute_reply.started": "2024-05-03T04:47:34.581009Z",
     "shell.execute_reply": "2024-05-03T04:47:36.764837Z"
    },
    "trusted": true
   },
   "execution_count": 6,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": "<Figure size 640x480 with 1 Axes>",
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAGdCAYAAAA44ojeAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/xnp5ZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA75ElEQVR4nO3deXgUVb7/8U9viYlmMYFsY9iVRQICaogLwiUKcUVwBhQdUAZEAyOgiPGqoN57w6jjMoo4jgrOKOLoZXFwxIcdl4CAICCIgCioCTAyJCyS9HJ+f3ipny3pQKBT3Q3v1/PU4+mq09XfOrSpb59TdcphjDECAACIIs5IBwAAAPBLJCgAACDqkKAAAICoQ4ICAACiDgkKAACIOiQoAAAg6pCgAACAqEOCAgAAoo470gEcj0AgoO+//15JSUlyOByRDgcAABwDY4z27dunnJwcOZ1195HEZILy/fffKzc3N9JhAACA47Bjxw6dddZZddaJyQQlKSlJ0k8HmJycHOFoAADAsaiqqlJubq51Hq9LTCYoh4d1kpOTSVBiiN/v17JlyyRJXbt2lcvlinBEAIBIOJbLM2IyQUFs8vv9mj9/viTpggsuIEEBAIREggLbOJ1OdezY0SoDABAKCQps43a71adPn0iHAQCIAfVKUEpLSzVjxgx98cUXSkhI0EUXXaQ//OEPat26tVXn0KFDuvvuuzV9+nRVV1erV69eev7555WZmWnV2b59u+644w4tWrRIZ5xxhgYNGqTS0lK53eRLAHAyMMbI5/PJ7/dHOhTYyOVyye12h2UKkHplBEuWLFFxcbEuuOAC+Xw+3X///briiiu0YcMGnX766ZKk0aNH691339Vbb72llJQUjRgxQn379tVHH30k6afrEK666iplZWXp448/Vnl5uX7729/K4/Hof/7nf074gAAAkVVTU6Py8nIdPHgw0qEgAhITE5Wdna24uLgT2o/DGGOO9827d+9WRkaGlixZom7duqmyslKNGzfWtGnTdMMNN0iSvvjiC7Vt21ZlZWXq2rWr3nvvPV199dX6/vvvrV6VF154QePGjdPu3buP6YCqqqqUkpKiyspK7uKJITU1NXryySclSWPGjDnhLy+A6BMIBLR582a5XC41btxYcXFxTKh5ijDGqKamRrt375bf79fZZ599xPWG9Tl/n9CYSmVlpSQpLS1NkrRq1Sp5vV4VFhZaddq0aaMmTZpYCUpZWZny8vKChnx69eqlO+64Q59//rk6dep0xOdUV1eruro66AARm37+7wjg5FNTU6NAIKDc3FwlJiZGOhzYLCEhQR6PR998841qamp02mmnHfe+jjtBCQQCGjVqlC6++GK1b99eklRRUaG4uDilpqYG1c3MzFRFRYVV5+fJyeHth7fVprS0VA8//PDxhooo4fF4NGLECKsM4OTFnXqnrnD92x/3XoqLi7V+/XpNnz49LIHUpaSkRJWVldayY8eOBv9MhJ/D4VB6errS09Pp8gUA1Om4EpQRI0Zozpw5WrRoUdBc+llZWaqpqdHevXuD6u/cuVNZWVlWnZ07dx6x/fC22sTHx1uzxjJ7LADgZOdwODRr1qxIhyFJmjBhgs477zzbP7deCYoxRiNGjNDMmTO1cOFCNW/ePGh7ly5d5PF4tGDBAmvdpk2btH37dhUUFEiSCgoKtG7dOu3atcuqM2/ePCUnJ6tdu3YnciyIcn6/X5988ok++eQTbj0EgCgUTYlRva5BKS4u1rRp0zR79mwlJSVZ14ykpKQoISFBKSkpGjJkiMaMGaO0tDQlJydr5MiRKigoUNeuXSVJV1xxhdq1a6dbbrlFjz32mCoqKvTAAw+ouLhY8fHx4T9CRA2/36/33ntPknTeeecx1T0AIKR69aBMnjxZlZWV6t69u7Kzs63lzTfftOo89dRTuvrqq9WvXz9169ZNWVlZmjFjhrXd5XJpzpw5crlcKigo0M0336zf/va3euSRR8J3VIhKTqdT7dq1U7t27biADkDU6d69u0aOHKlRo0bpzDPPVGZmpv7yl7/owIEDuvXWW5WUlKRWrVpZP7Skn354DRkyRM2bN1dCQoJat26tZ555xtp+6NAhnXvuuRo2bJi1buvWrUpKStIrr7xyzLHt2LFDv/nNb5Samqq0tDRdd911+vrrr63tgwcPVp8+ffTEE08oOztb6enpKi4ultfrteqUl5frqquuUkJCgpo3b65p06apWbNmevrppyVJzZo1kyRdf/31cjgc1uvD/va3v6lZs2ZKSUnRgAEDtG/fvmOO/7iYGFRZWWkkmcrKykiHAgD4mR9//NFs2LDB/Pjjj0dsq66uNtXV1SYQCFjrfD6fqa6uNl6vN6x1j8dll11mkpKSzKOPPmq+/PJL8+ijjxqXy2WKiorMiy++aL788ktzxx13mPT0dHPgwAFjjDE1NTXmoYceMitWrDBfffWVee2110xiYqJ58803rf2uXr3axMXFmVmzZhmfz2e6du1qrr/++jpjkWRmzpxpfUbbtm3NbbfdZtauXWs2bNhgbrrpJtO6dWtTXV1tjDFm0KBBJjk52QwfPtxs3LjR/OMf/zCJiYnmxRdftPZZWFhozjvvPLNs2TKzatUqc9lll5mEhATz1FNPGWOM2bVrl5FkpkyZYsrLy82uXbuMMcaMHz/enHHGGaZv375m3bp1ZunSpSYrK8vcf//9tcZe13egPudvEhQAQNjUdXKaMGGCmTBhgtm/f7+1bsmSJWbChAlm9uzZQXX/+7//20yYMMH8+9//ttaVlZWZCRMmmP/93/8NqvvYY4+ZCRMmmJ07d55Q7Jdddpm55JJLrNc+n8+cfvrp5pZbbrHWlZeXG0mmrKws5H6Ki4tNv379joixUaNGZsSIESY7O9v861//qjOWnycof/vb30zr1q2DErDq6mqTkJBg3n//fWPMTwlK06ZNjc/ns+r8+te/Nv379zfGGLNx40YjyaxYscLavnnzZiPJSlB++bmHjR8/3iQmJpqqqipr3dixY01+fn6tsYcrQeHhNwAA/J8OHTpYZZfLpfT0dOXl5VnrDs/b9fMbPSZNmqRXXnlF27dv148//qiampoj7nq5++67NWvWLD333HN67733lJ6efswxffbZZ9qyZYuSkpKC1h86dEhbt261Xp977rlB1/ZlZ2dr3bp1kn66YcXtdqtz587W9latWunMM888phiaNWsW9PnZ2dlBbdAQSFBgG6/Xq2effVaSNHLkSCZrA04xJSUlkoInarz44ovVtWvXI65Lu+eee46oe8EFF6hz585H1L3rrruOqHu8frkPh8MRtO7wHE6BQECSNH36dN1zzz364x//qIKCAiUlJenxxx/X8uXLg/aza9cuffnll3K5XNq8ebN69+59zDHt379fXbp00euvv37EtsaNG9cZ++E4T1RD7jsUEhTYxhhjXVRljv8RUABiVG3P33K5XLXe0Xeide3y0Ucf6aKLLtKdd95prft5r8Zht912m/Ly8jRkyBANHTpUhYWFatu27TF9RufOnfXmm28qIyPjuOcBa926tXw+n1avXq0uXbpIkrZs2aJ///vfQfU8Hk/UTAPBrRSwjdvt1u23367bb79dbje5MYDYd/bZZ2vlypV6//339eWXX+rBBx/UihUrgupMmjRJZWVlevXVVzVw4ED16dNHAwcOVE1NzTF9xsCBA9WoUSNdd911+uCDD7Rt2zYtXrxYv//97/Xtt98e0z7atGmjwsJCDRs2TJ988olWr16tYcOGKSEhIWhm72bNmmnBggWqqKg4InmxGwkKbON0OpWVlaWsrCxuMwZwUrj99tvVt29f9e/fX/n5+frhhx+CelO++OILjR07Vs8//7xyc3MlSc8//7z+9a9/6cEHHzymz0hMTNTSpUvVpEkT9e3bV23bttWQIUN06NChevWo/PWvf1VmZqa6deum66+/XkOHDlVSUlLQA/3++Mc/at68ecrNza314b12cpgY7Guvz+OaAQD2OXTokLZt26bmzZuf0JNs0fC+/fZb5ebmav78+erZs2fY9lvXd6A+52/62WEbv99vXVGel5fHTLIAYKOFCxdq//79ysvLU3l5ue699141a9ZM3bp1i3RotSJBgW38fr9mz54tSWrXrh0JCgDYyOv16v7779dXX32lpKQkXXTRRXr99dej9o5KEhTYxul06uyzz7bKAAD79OrVS7169Yp0GMeMBAW2cbvduummmyIdBgAgBvAzFgAARB0SFABA2MXgDaIIk3D92zPEA9t4vV698MILkqThw4dH7YVZAI7f4f+vDx48qISEhAhHg0g4ePCgpBN/9AAJCmxjjNGePXusMoCTj8vlUmpqqvUgucTExKCZSnHyMsbo4MGD2rVrl1JTU0/4Tk0SFNjG7Xbr1ltvtcoATk5ZWVmS1OBPu0V0Sk1Ntb4DJ4KzBGzjdDrVpEmTSIcBoIE5HA5lZ2crIyNDXq830uHARh6PJ2xzXJGgAAAaRKinDwPHggQFtgkEAtq4caMkqW3btkzWBgAIiTMEbOPz+fT222/r7bffls/ni3Q4AIAoRg8KbONwONS0aVOrDABAKCQosI3H49HgwYMjHQYAIAYwxAMAAKIOCQoAAIg6DPHANl6vVy+//LIkaciQIUx1DwAIiQQFtjHGaOfOnVYZAIBQSFBgG7fbrZtvvtkqAwAQCmcJ2MbpdKply5aRDgMAEAO4SBYAAEQdelBgm0AgoC1btkiSWrVqxVT3AICQOEPANj6fT2+88YbeeOMNproHANSJHhTYxuFwKCcnxyoDABAKCQps4/F4NHTo0EiHAQCIAQzxAACAqFPvBGXp0qW65pprlJOTI4fDoVmzZgVtdzgctS6PP/64VadZs2ZHbJ84ceIJHwwAADg51HuI58CBA+rYsaNuu+029e3b94jt5eXlQa/fe+89DRkyRP369Qta/8gjjwR19yclJdU3FMQYr9erv/3tb5KkW265hanuAQAh1TtBKSoqUlFRUcjtWVlZQa9nz56tHj16qEWLFkHrk5KSjqiLk5sxRjt27LDKAACE0qDXoOzcuVPvvvuuhgwZcsS2iRMnKj09XZ06ddLjjz9e522n1dXVqqqqCloQe9xut/r376/+/fsz1T0AoE4NepZ49dVXlZSUdMRQ0O9//3t17txZaWlp+vjjj1VSUqLy8nI9+eSTte6ntLRUDz/8cEOGChs4nU61adMm0mEAAGKAw5xAX7vD4dDMmTPVp0+fWre3adNGl19+uZ599tk69/PKK6/o9ttv1/79+xUfH3/E9urqalVXV1uvq6qqlJubq8rKSiUnJx9v+AAAwEZVVVVKSUk5pvN3g/WgfPDBB9q0aZPefPPNo9bNz8+Xz+fT119/rdatWx+xPT4+vtbEBbElEAho+/btkqQmTZow1T0AIKQGO0O8/PLL6tKlizp27HjUumvWrJHT6VRGRkZDhYMo4PP59Oqrr+rVV19lqnsAQJ3q3YOyf/9+64FvkrRt2zatWbNGaWlpatKkiaSfunDeeust/fGPfzzi/WVlZVq+fLl69OihpKQklZWVafTo0br55pt15plnnsChINo5HA41btzYKgMAEEq9r0FZvHixevToccT6QYMGaerUqZKkF198UaNGjVJ5eblSUlKC6n366ae688479cUXX6i6ulrNmzfXLbfcojFjxhzzME59xrAAAEB0qM/5+4Quko0UEhQAAGJPfc7fXKUIAACiDrNlwTZer1fTp0+XJA0YMICp7gEAIZGgwDbGGH311VdWGQCAUEhQYBu3263rr7/eKgMAEApnCdjG6XSqQ4cOkQ4DABADuEgWAABEHXpQYJtAIKDy8nJJUnZ2NlPdAwBC4gwB2/h8Pr300kt66aWXmOoeAFAnelBgG4fDYc0szFT3AIC6kKDANh6PR6NGjYp0GACAGMAQDwAAiDokKAAAIOowxAPb+Hw+vf3225KkG264gcnaAAAhcYaAbQKBgDZt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"
     },
     "metadata": {}
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Tokenizer"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "class Tokenizer:\n",
    "    def __init__(self, word2idx, idx2word, max_length=500, pad_idx=0, bos_idx=1, eos_idx=3, unk_idx=2):\n",
    "        self.word2idx = word2idx\n",
    "        self.idx2word = idx2word\n",
    "        self.max_length = max_length\n",
    "        self.pad_idx = pad_idx\n",
    "        self.bos_idx = bos_idx\n",
    "        self.eos_idx = eos_idx\n",
    "        self.unk_idx = unk_idx\n",
    "    \n",
    "    def encode(self, text_list, padding_first=False):\n",
    "        \"\"\"如果padding_first == True，则padding加载前面，否则加载后面\"\"\"\n",
    "        max_length = min(self.max_length, 2 + max([len(text) for text in text_list]))\n",
    "        indices_list = []\n",
    "        for text in text_list:\n",
    "            indices = [self.bos_idx] + [self.word2idx.get(word, self.unk_idx) for word in text[:max_length-2]] + [self.eos_idx]\n",
    "            if padding_first:\n",
    "                indices = [self.pad_idx] * (max_length - len(indices)) + indices\n",
    "            else:\n",
    "                indices = indices + [self.pad_idx] * (max_length - len(indices))\n",
    "            indices_list.append(indices)\n",
    "        return torch.tensor(indices_list)\n",
    "    \n",
    "    \n",
    "    def decode(self, indices_list, remove_bos=True, remove_eos=True, remove_pad=True, split=False):\n",
    "        text_list = []\n",
    "        for indices in indices_list:\n",
    "            text = []\n",
    "            for index in indices:\n",
    "                word = self.idx2word.get(index, \"[UNK]\")\n",
    "                if remove_bos and word == \"[BOS]\":\n",
    "                    continue\n",
    "                if remove_eos and word == \"[EOS]\":\n",
    "                    break\n",
    "                if remove_pad and word == \"[PAD]\":\n",
    "                    break\n",
    "                text.append(word)\n",
    "            text_list.append(\" \".join(text) if not split else text)\n",
    "        return text_list\n",
    "    \n",
    "\n",
    "tokenizer = Tokenizer(word2idx=word2idx, idx2word=idx2word)\n",
    "raw_text = [\"hello world\".split(), \"tokenize text datas with batch\".split(), \"this is a test\".split()]\n",
    "indices = tokenizer.encode(raw_text, padding_first=True)\n",
    "decode_text = tokenizer.decode(indices.tolist(), remove_bos=False, remove_eos=False, remove_pad=False)\n",
    "print(\"raw text\")\n",
    "for raw in raw_text:\n",
    "    print(raw)\n",
    "print(\"indices\")\n",
    "for index in indices:\n",
    "    print(index)\n",
    "print(\"decode text\")\n",
    "for decode in decode_text:\n",
    "    print(decode)"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:28.841714100Z",
     "start_time": "2024-05-02T08:32:28.818725300Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:36.767290Z",
     "iopub.execute_input": "2024-05-03T04:47:36.767595Z",
     "iopub.status.idle": "2024-05-03T04:47:36.811355Z",
     "shell.execute_reply.started": "2024-05-03T04:47:36.767569Z",
     "shell.execute_reply": "2024-05-03T04:47:36.810435Z"
    },
    "trusted": true
   },
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "text": "raw text\n['hello', 'world']\n['tokenize', 'text', 'datas', 'with', 'batch']\n['this', 'is', 'a', 'test']\nindices\ntensor([   0,    0,    0,    1, 4825,  182,    3])\ntensor([    1,     2,  3004,     2,    19, 19233,     3])\ntensor([   0,    1,   14,    9,    6, 2181,    3])\ndecode text\n[PAD] [PAD] [PAD] [BOS] hello world [EOS]\n[BOS] [UNK] text [UNK] with batch [EOS]\n[PAD] [BOS] this is a test [EOS]\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "# 看看训练集的数据\n",
    "\n",
    "tokenizer.decode(train_data[:2], remove_bos=False, remove_eos=False, remove_pad=False)"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:36.812516Z",
     "iopub.execute_input": "2024-05-03T04:47:36.812799Z",
     "iopub.status.idle": "2024-05-03T04:47:36.819435Z",
     "shell.execute_reply.started": "2024-05-03T04:47:36.812774Z",
     "shell.execute_reply": "2024-05-03T04:47:36.818339Z"
    },
    "trusted": true
   },
   "execution_count": 8,
   "outputs": [
    {
     "execution_count": 8,
     "output_type": "execute_result",
     "data": {
      "text/plain": "[\"[BOS] this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert [UNK] is an amazing actor and now the same being director [UNK] father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for [UNK] and would recommend it to everyone to watch and the fly fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also [UNK] to the two little boy's that played the [UNK] of norman and paul they were just brilliant children are often left out of the [UNK] list i think because the stars that play them all grown up are such a big profile for the whole film but these children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was shared with us all\",\n \"[BOS] big hair big boobs bad music and a giant safety pin these are the words to best describe this terrible movie i love cheesy horror movies and i've seen hundreds but this had got to be on of the worst ever made the plot is paper thin and ridiculous the acting is an abomination the script is completely laughable the best is the end showdown with the cop and how he worked out who the killer is it's just so damn terribly written the clothes are sickening and funny in equal [UNK] the hair is big lots of boobs [UNK] men wear those cut [UNK] shirts that show off their [UNK] sickening that men actually wore them and the music is just [UNK] trash that plays over and over again in almost every scene there is trashy music boobs and [UNK] taking away bodies and the gym still doesn't close for [UNK] all joking aside this is a truly bad film whose only charm is to look back on the disaster that was the 80's and have a good old laugh at how bad everything was back then\"]"
     },
     "metadata": {}
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 数据集与 DataLoader"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "class IMDBDataset(Dataset):\n",
    "    def __init__(self, data, labels, remain_length=True):\n",
    "        if remain_length:\n",
    "            self.data = tokenizer.decode(data, remove_bos=False, remove_eos=False, remove_pad=False)\n",
    "        else:\n",
    "            # 缩减一下数据\n",
    "            self.data = tokenizer.decode(data)\n",
    "        self.labels = labels\n",
    "    \n",
    "    def __getitem__(self, index):\n",
    "        text = self.data[index]\n",
    "        label = self.labels[index]\n",
    "        return text, label\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.data)\n",
    "    \n",
    "    \n",
    "def collate_fct(batch):\n",
    "    text_list = [item[0].split() for item in batch]\n",
    "    label_list = [item[1] for item in batch]\n",
    "    # 这里使用 padding first\n",
    "    text_list = tokenizer.encode(text_list, padding_first=True).to(dtype=torch.int)\n",
    "    return text_list, torch.tensor(label_list).reshape(-1, 1).to(dtype=torch.float)\n",
    "\n",
    "\n",
    "# 用RNN，缩短序列长度\n",
    "train_ds = IMDBDataset(train_data, train_labels, remain_length=False)\n",
    "test_ds = IMDBDataset(test_data, test_labels, remain_length=False)"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:32:41.820591900Z",
     "start_time": "2024-05-02T08:32:36.227566100Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:36.820601Z",
     "iopub.execute_input": "2024-05-03T04:47:36.820915Z",
     "iopub.status.idle": "2024-05-03T04:47:42.935725Z",
     "shell.execute_reply.started": "2024-05-03T04:47:36.820890Z",
     "shell.execute_reply": "2024-05-03T04:47:42.934882Z"
    },
    "trusted": true
   },
   "execution_count": 9,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "batch_size = 128\n",
    "train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True, collate_fn=collate_fct)\n",
    "test_dl = DataLoader(test_ds, batch_size=batch_size, shuffle=False, collate_fn=collate_fct)"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:33:12.220977300Z",
     "start_time": "2024-05-02T08:33:12.195716900Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:42.940057Z",
     "iopub.execute_input": "2024-05-03T04:47:42.940354Z",
     "iopub.status.idle": "2024-05-03T04:47:42.945758Z",
     "shell.execute_reply.started": "2024-05-03T04:47:42.940327Z",
     "shell.execute_reply": "2024-05-03T04:47:42.944620Z"
    },
    "trusted": true
   },
   "execution_count": 10,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 定义模型"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "class LSTM(nn.Module):\n",
    "    def __init__(self, embedding_dim=16, hidden_dim=64, vocab_size=vocab_size, num_layers=1, bidirectional=False):\n",
    "        super(LSTM, self).__init__()\n",
    "        self.embeding = nn.Embedding(vocab_size, embedding_dim)\n",
    "        self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers=num_layers, batch_first=True, bidirectional=bidirectional)\n",
    "        self.layer = nn.Linear(hidden_dim * (2 if bidirectional else 1), hidden_dim)\n",
    "        self.fc = nn.Linear(hidden_dim, 1)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # [bs, seq length]\n",
    "        x = self.embeding(x)\n",
    "        # [bs, seq length, embedding_dim] -> shape [bs, embedding_dim, seq length]\n",
    "        seq_output, (hidden, cell) = self.lstm(x)\n",
    "        # [bs, seq length, hidden_dim], [*, bs, hidden_dim]\n",
    "        x = seq_output[:, -1, :]\n",
    "        # 取最后一个时间步的输出 (这也是为什么要设置padding_first=True的原因)\n",
    "        x = self.layer(x)\n",
    "        x = self.fc(x)\n",
    "        return x\n",
    "    \n",
    "sample_inputs = torch.randint(0, vocab_size, (2, 128))\n",
    "    \n",
    "print(\"{:=^80}\".format(\" 一层单向 LSTM \"))       \n",
    "for key, value in LSTM().named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")\n",
    "\n",
    "    \n",
    "print(\"{:=^80}\".format(\" 一层双向 LSTM \"))       \n",
    "for key, value in LSTM(bidirectional=True).named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")\n",
    "\n",
    "    \n",
    "print(\"{:=^80}\".format(\" 两层单向 LSTM \"))       \n",
    "for key, value in LSTM(num_layers=2).named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")\n"
   ],
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:33:48.336669800Z",
     "start_time": "2024-05-02T08:33:48.283700100Z"
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:42.947030Z",
     "iopub.execute_input": "2024-05-03T04:47:42.947353Z",
     "iopub.status.idle": "2024-05-03T04:47:42.981775Z",
     "shell.execute_reply.started": "2024-05-03T04:47:42.947327Z",
     "shell.execute_reply": "2024-05-03T04:47:42.980874Z"
    },
    "trusted": true
   },
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "text": "================================== 一层单向 LSTM ===================================\n            embeding.weight             paramerters num: 160000\n           lstm.weight_ih_l0            paramerters num: 4096\n           lstm.weight_hh_l0            paramerters num: 16384\n            lstm.bias_ih_l0             paramerters num: 256\n            lstm.bias_hh_l0             paramerters num: 256\n              layer.weight              paramerters num: 4096\n               layer.bias               paramerters num: 64\n               fc.weight                paramerters num: 64\n                fc.bias                 paramerters num: 1\n================================== 一层双向 LSTM ===================================\n            embeding.weight             paramerters num: 160000\n           lstm.weight_ih_l0            paramerters num: 4096\n           lstm.weight_hh_l0            paramerters num: 16384\n            lstm.bias_ih_l0             paramerters num: 256\n            lstm.bias_hh_l0             paramerters num: 256\n       lstm.weight_ih_l0_reverse        paramerters num: 4096\n       lstm.weight_hh_l0_reverse        paramerters num: 16384\n        lstm.bias_ih_l0_reverse         paramerters num: 256\n        lstm.bias_hh_l0_reverse         paramerters num: 256\n              layer.weight              paramerters num: 8192\n               layer.bias               paramerters num: 64\n               fc.weight                paramerters num: 64\n                fc.bias                 paramerters num: 1\n================================== 两层单向 LSTM ===================================\n            embeding.weight             paramerters num: 160000\n           lstm.weight_ih_l0            paramerters num: 4096\n           lstm.weight_hh_l0            paramerters num: 16384\n            lstm.bias_ih_l0             paramerters num: 256\n            lstm.bias_hh_l0             paramerters num: 256\n           lstm.weight_ih_l1            paramerters num: 16384\n           lstm.weight_hh_l1            paramerters num: 16384\n            lstm.bias_ih_l1             paramerters num: 256\n            lstm.bias_hh_l1             paramerters num: 256\n              layer.weight              paramerters num: 4096\n               layer.bias               paramerters num: 64\n               fc.weight                paramerters num: 64\n                fc.bias                 paramerters num: 1\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "4 * 16 * 64 #lstm.weight_ih_l0"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-02T08:36:09.545313600Z",
     "start_time": "2024-05-02T08:36:09.506335700Z"
    },
    "jupyter": {
     "outputs_hidden": false
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:42.982885Z",
     "iopub.execute_input": "2024-05-03T04:47:42.983224Z",
     "iopub.status.idle": "2024-05-03T04:47:42.989768Z",
     "shell.execute_reply.started": "2024-05-03T04:47:42.983190Z",
     "shell.execute_reply": "2024-05-03T04:47:42.988745Z"
    },
    "trusted": true
   },
   "execution_count": 12,
   "outputs": [
    {
     "execution_count": 12,
     "output_type": "execute_result",
     "data": {
      "text/plain": "4096"
     },
     "metadata": {}
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "4* 64*64 #lstm.weight_hh_l0"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-02T08:36:14.836046500Z",
     "start_time": "2024-05-02T08:36:14.799050900Z"
    },
    "jupyter": {
     "outputs_hidden": false
    },
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:42.991003Z",
     "iopub.execute_input": "2024-05-03T04:47:42.991308Z",
     "iopub.status.idle": "2024-05-03T04:47:42.998461Z",
     "shell.execute_reply.started": "2024-05-03T04:47:42.991280Z",
     "shell.execute_reply": "2024-05-03T04:47:42.997549Z"
    },
    "trusted": true
   },
   "execution_count": 13,
   "outputs": [
    {
     "execution_count": 13,
     "output_type": "execute_result",
     "data": {
      "text/plain": "16384"
     },
     "metadata": {}
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 训练"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        # 二分类\n",
    "        preds = logits > 0\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "        \n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc\n"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:42.999576Z",
     "iopub.execute_input": "2024-05-03T04:47:42.999917Z",
     "iopub.status.idle": "2024-05-03T04:47:43.091789Z",
     "shell.execute_reply.started": "2024-05-03T04:47:42.999882Z",
     "shell.execute_reply": "2024-05-03T04:47:43.091056Z"
    },
    "trusted": true
   },
   "execution_count": 14,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "### TensorBoard 可视化\n",
    "\n",
    "\n",
    "训练过程中可以使用如下命令启动tensorboard服务。\n",
    "\n",
    "```shell\n",
    "tensorboard \\\n",
    "    --logdir=runs \\     # log 存放路径\n",
    "    --host 0.0.0.0 \\    # ip\n",
    "    --port 8848         # 端口\n",
    "```"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n",
    "\n",
    "    def draw_model(self, model, input_shape):\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n",
    "        \n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\", \n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "            )\n",
    "        \n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )\n",
    "        \n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "            \n",
    "        )\n",
    "    \n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)\n"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:43.092913Z",
     "iopub.execute_input": "2024-05-03T04:47:43.093218Z",
     "iopub.status.idle": "2024-05-03T04:47:43.118190Z",
     "shell.execute_reply.started": "2024-05-03T04:47:43.093169Z",
     "shell.execute_reply": "2024-05-03T04:47:43.117453Z"
    },
    "trusted": true
   },
   "execution_count": 15,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Save Best\n"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch. \n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = -1\n",
    "        \n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "        \n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "        \n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))\n",
    "\n"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:43.119248Z",
     "iopub.execute_input": "2024-05-03T04:47:43.119557Z",
     "iopub.status.idle": "2024-05-03T04:47:43.129100Z",
     "shell.execute_reply.started": "2024-05-03T04:47:43.119532Z",
     "shell.execute_reply": "2024-05-03T04:47:43.128085Z"
    },
    "trusted": true
   },
   "execution_count": 16,
   "outputs": []
  },
  {
   "cell_type": "markdown",
   "source": [
    "### Early Stop"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:43.130506Z",
     "iopub.execute_input": "2024-05-03T04:47:43.130817Z",
     "iopub.status.idle": "2024-05-03T04:47:43.140541Z",
     "shell.execute_reply.started": "2024-05-03T04:47:43.130781Z",
     "shell.execute_reply": "2024-05-03T04:47:43.139593Z"
    },
    "trusted": true
   },
   "execution_count": 17,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                preds = logits > 0\n",
    "            \n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "                    \n",
    "                    # 1. 使用 tensorboard 可视化\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(\n",
    "                            global_step, \n",
    "                            loss=loss, val_loss=val_loss,\n",
    "                            acc=acc, val_acc=val_acc,\n",
    "                            lr=optimizer.param_groups[0][\"lr\"],\n",
    "                            )\n",
    "                \n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(val_acc)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 20\n",
    "\n",
    "model = LSTM()\n",
    "\n",
    "# 1. 定义损失函数 采用交叉熵损失 (但是二分类)\n",
    "loss_fct = F.binary_cross_entropy_with_logits\n",
    "# 2. 定义优化器 采用 adam\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 1. tensorboard 可视化\n",
    "if not os.path.exists(\"runs\"):\n",
    "    os.mkdir(\"runs\")\n",
    "tensorboard_callback = TensorBoardCallback(\"runs/imdb-lstm\")\n",
    "# tensorboard_callback.draw_model(model, [1, MAX_LENGTH])\n",
    "# 2. save best\n",
    "if not os.path.exists(\"checkpoints\"):\n",
    "    os.makedirs(\"checkpoints\")\n",
    "save_ckpt_callback = SaveCheckpointsCallback(\"checkpoints/imdb-lstm\", save_step=len(train_dl), save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10)\n",
    "\n",
    "\n",
    "# 如果有可用的多个GPU\n",
    "# if torch.cuda.device_count() > 1:\n",
    "#     print(\"使用多个GPU进行训练...\")\n",
    "#     model = nn.DataParallel(model)\n",
    "\n"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:43.142057Z",
     "iopub.execute_input": "2024-05-03T04:47:43.142394Z",
     "iopub.status.idle": "2024-05-03T04:47:44.062187Z",
     "shell.execute_reply.started": "2024-05-03T04:47:43.142363Z",
     "shell.execute_reply": "2024-05-03T04:47:44.061381Z"
    },
    "trusted": true
   },
   "execution_count": 18,
   "outputs": []
  },
  {
   "cell_type": "code",
   "source": [
    "model = model.to(device)\n",
    "start=time.time()\n",
    "record = training(\n",
    "    model, \n",
    "    train_dl, \n",
    "    test_dl, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=tensorboard_callback,\n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_dl)\n",
    "    )\n",
    "end=time.time()\n",
    "print(f'use time{end-start}')"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:47:44.063276Z",
     "iopub.execute_input": "2024-05-03T04:47:44.063556Z",
     "iopub.status.idle": "2024-05-03T04:53:29.669289Z",
     "shell.execute_reply.started": "2024-05-03T04:47:44.063531Z",
     "shell.execute_reply": "2024-05-03T04:53:29.668367Z"
    },
    "trusted": true
   },
   "execution_count": 19,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": "  0%|          | 0/3920 [00:00<?, ?it/s]",
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "035feb25a78445beb2fcb9e6cf05e539"
      }
     },
     "metadata": {}
    },
    {
     "name": "stdout",
     "text": "use time345.3171458244324\n",
     "output_type": "stream"
    }
   ]
  },
  {
   "cell_type": "code",
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns)\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5))\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        # axs[idx].set_xticks(range(0, train_df.index[-1], 5000))\n",
    "        # axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", range(0, train_df.index[-1], 5000)))\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=10)  #横坐标是 steps"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:53:29.670641Z",
     "iopub.execute_input": "2024-05-03T04:53:29.671094Z",
     "iopub.status.idle": "2024-05-03T04:53:30.081623Z",
     "shell.execute_reply.started": "2024-05-03T04:53:29.671059Z",
     "shell.execute_reply": "2024-05-03T04:53:30.080600Z"
    },
    "trusted": true
   },
   "execution_count": 20,
   "outputs": [
    {
     "output_type": "display_data",
     "data": {
      "text/plain": "<Figure size 1000x500 with 2 Axes>",
      "image/png": "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v/3229mxYwd//etfyc7OZvr06Xz88cfce++9tXaMRu8R/+9wbX9F+x5pyO8Pj8fDH//4R7p06UJ8fDy9evXi5ZdfDltv5syZgfdM27ZtmTRpUuCx48ePc9ttt5GRkUFcXBz9+vXjm2++iWr/QohgM5fsZNL7v+H2RNe4ZOXOo1z75gq2HS6q5SOrOskM+dw+axW/Hy7ip61H2PXcufV9OEI0KqUuD30f/a5e9r3pyXEk2KL7U/byyy+zdetW+vXrx5NPPgnAxo0bAXjggQd48cUX6dq1K2lpaezdu5cJEybw9NNPY7fbeeedd5g4cSJbtmyhY8eOEffxxBNP8Pzzz/PCCy/wyiuvcM0117B7925atmxZpde1atUqLr/8ch5//HGuuOIKli1bxp133kl6ejo33HADv/76K3/+85+ZNWsWI0eO5OjRoyxevBiAgwcPctVVV/H8889z0UUXUVhYyOLFi6sUODYmv/76K2eeeWbgZ//Ynuuvv563336bgwcPBgIjgC5dujB79mzuvfdeXn75Zdq3b88bb7wR07baoRrDe6Qhvz+8Xi/t27fnk08+IT09nWXLlnHrrbeSkZHBOeecA8C///1vJk+ezHPPPcf48ePJz89n6dKlge3Hjx9PYWEh7777Lt26dWPTpk1NvkucELXlyW82AXBOv0zOG9Cu0vWvn7mSUpeHG99eyeK/nlXbh1clEgz5HMwvq+9DEELUshYtWmCz2UhISCAzMxOA7OxsAJ588knGjBkTWLdly5YMHDgw8PNTTz3FF198wddffx10tznUDTfcwFVXXQXAM888wz//+U9WrlwZuGCL1tSpUzn77LN55JFHAOjZsyebNm3ihRde4IYbbmDPnj0kJiZy3nnnkZycTKdOnRg8eDCgBUNut5uLL76YTp06AdC/f/8q7b8xOeOMMyoM9N5++23DbVavXl2LR9X4NOT3h9VqDerm16VLF5YvX84nn3wS2Pbvf/879913X1DDhpNOOgmA77//npUrV7J582Z69uwJaA0ehBA1k1dUccdMv1KXB4C9R0tr83CqRYIhnybazEeIOhFvNbPpydq7qx7K6/VSWFBIckoy8dbY3NkdOnRo0M9FRUU8/vjjzJ49OxBclJaWBmUYjAwYMCDwfWJiIikpKRw+fLjKx7N582YuuOCCoGWjRo1i2rRpeDwexowZQ6dOnejatSvnnHMO55xzTqD8aODAgZx99tn079+fcePGMXbsWC699FLS0tKqfBwiNkLfI/rf4dpuoBCL90hDeH+8+uqrzJw5kz179lBaWorT6WTQoEEAHD58mAMHDnD22WcbbrtmzRrat28fCISEELFR5gtyKpNst1DoaJgt6iUY8lEkGhKi2kwmU9SlarHg9Xpx28wk2Cwxa6cb2hXu/vvvZ/78+bz44ot0796d+Ph4Lr300krnjQntcGMymWplUs3k5GR+++03Fi1axLx583j00Ud5/PHH+eWXX0hNTWX+/PksW7aMefPm8corr/DQQw+xYsUKunTpEvNjEZULfY/of4cbUje5SOr7/fHhhx9y//3389JLLzFixAiSk5N54YUXWLFiBUDELoB+lT0uRHOhqipur4rVHPx3x+XxYlFMVf5MLXOVv389XhVVVbH4ntvp9mKzaN9npcWTfUibD6ygzEVKXMPpttfw/wLXEUViISGaBZvNhsdT+Z2spUuXcsMNN3DRRRfRv39/MjMz2bVrV+0foE+fPn0C4x30x9SzZ8/AOAeLxcLo0aN5/vnnWbduHbt27WLhwoWAdpE5atQonnjiCVavXo3NZuOLL76os+MXjVNDfX8sXbqUkSNHcueddzJ48GC6d+/O9u3bA48nJyfTuXNnFixYYLj9gAED2LdvH1u3bq21YxSiMbjlnVWMem4hhWWuwLLCMhcjn1vI7e+uqvLzleoyQ1e+tpyzXvqRMpeHfy74nQFPfMeG/fkAQcHX1kMNa7JpyQz5SGZIiOahc+fOrFixgl27dpGUlBTxrnSPHj34/PPPmThxIiaTiUceeaRWMjyR3HfffZx00kk89dRTXHHFFSxfvpx//etfTJ8+HYBvvvmGHTt2cNppp5GWlsacOXPwer306tWLFStWsGDBAsaOHUubNm1YsWIFR44coU+fPnV2/KJxaqjvjx49evDOO+/w3Xff0aVLF2bNmsUvv/wSlOl8/PHHuf3222nTpk2gWcLSpUv505/+xOmnn85pp53GJZdcwtSpU+nevTvZ2dmYTKYqj+cTojH7frM2x9p3G3O4dEj7wPdHCh18tzGnok0DPN7yMZr+MrlSp4dfdh0DtM5xU+drNx7+PnsTH946ghJneYnc4UJHzV9IDElmyKepzgAuhAh2//33Yzab6du3L61bt444xmHq1KmkpaUxcuRIJk6cyLhx4zjxxBPr7DhPPPFEPv74Yz788EP69evHo48+ypNPPskNN9wAQGpqKp9//jlnnXUWffr0YcaMGXzwwQeccMIJpKSk8NNPPzFhwgR69uzJww8/zEsvvcT48ePr7PhF49RQ3x+33XYbF198MVdccQXDhw8nLy+PO++8M2id66+/nmnTpjF9+nROOOEEzjvvPH7//ffA45999hknnXQSV111FX379uWvf/1rVFkwIZqiIl1mSM/rrbzrqEvXTtsfDOUVlwc4B46XN0nwZ4RKneXvtcII+64vkhnyMUtYKESz0LNnT5YvXx60zB9g6HXu3DlQcuZ31113Bf0cWhZk1NHs+PHjUR2XUUe0Sy65hEsuucRw/VNOOYVFixYZPtanTx/mzp0b1X6F0Guo7w+73c5bb73FW2+9FbT86aefpqCgIPDzbbfdxm233Wb4HC1btmTmzJlR7U+Ipkif0Sl2Gt8IKHF5SLJXHB4YBkO6rnJbc8rnErL5LrBLXPpgqGE1UpAQwEfK5IQQQgghhN+G/fnsO1ZS6XpOt5clv+dG3VktWl6vyrLtuRSEZFKKHW6Wbc8NCm70ftl1lLyi8FI0h7v8+Ip8nd2OFDr4eUdeYHlFWZv1+/LZlVvMj1uPBJYt2ZbHnrwSvlyzP7Bs5tKdge935hXz1Zr9HC/Rj1GSYKhBklBICFGbbr/9dpKSkgy/br/99vo+PCHqlbw/REOz92gJ572yhFP+74dK131p/hb+8OYKHv3f5pgew/sr93D16yu46a1fgpbf+NYvXP36Ct5YvCNsm5+2HuGyGcs548VFYY85dJ3fin3B0LhpP/Hpqn2B5ZEClV25xUz81xLOeHERk94vn6Mtt8jBaS/8wFtLdxlut+NIMXd/uCZoWUMLhqRMzkfGDAkhatOTTz7J/fffb/hYSkpKHR+NEA2LvD9EQ7PpYEHlK/n850ctKPli9QHOGBG7Y3hvhTZm79fdx4KWr9x1FIAPf9nLbad3C3psYbY2b5dRwFGmywwd82VqjhYHt8OPlBmqyvmojIwZaqAawTQPQohGrE2bNrRp06a+D0OIBkneH6KhMRjiVuf0ZW1GjG7jVzTsQz8nUG6hw3AcX0GErE3ovESRnNqjFYt/z61wnYaWGZIQwEfGDAkhhBBCCAhu+BFNh7Xa4HRX3K7e6Kgqiln0Y5ryih0UlIYHJUURg6HorpO7tU6qdJ1CR8PKDEkw5CPBkBBCCCFE47B+Xz4vfJcdNH9NLOkDDVcFc2gZjdsxcriwjOe+zWZPXnBDhtV7jvHSvC0UOdy8NG8L763YzQOfrWPyx2vYd6w0wrOVK3K4eeG7bDYe0CY3rTgzVB4Mbc0p4v5P14atU1jmZsHmHGb8uD0oIHR5ogsI46zmStdZui2PuRsORfV8dUHK5HwUiYWEEEIIIRqFif9aAoDHCw+M7x3z59dXkLk8Kkbdpn/PKeTvs4ObJkRKIt39wRqW78jjf2sPsPSBswLLL5q+DID/rT3ArrzKO9fpmYBp87fyxpKdvPrDdnY9d26FY+D1ZXIA8zeFT7JaWObiwS/WAzCwfSojuqX7to2uU96wLmnM+LHy9W5/dxW7njs3quesbZIZ8pHMkBBCCCFE4+LPiMSaqssNRSpXK3SEZ6WKIySqlvvaV+8/bpztqSwQMgpGVGDzoeDGBvoyudAxQZWNQYLg8TwH88uPNZpg6NbTunJmr+jH/sW6FXl1STDkI8GQEEIIIUTjUluNDvRz+OgnGdUrNgiGCmM0HOakzmnBzxthLI8tZJCQ/nrWERLEhWaGjOQVh89PBFBmEBB2b5OE3VK+/0tObF+l7sx5IZ3s6osEQz4SCwkhotG5c2emTZsW1bomk4kvv/yyVo9HiIakKu8PIWLBW0vRkH5OnkiZIaNmA0Wu2FxQ9s4MbilfZBB4mQC7JXiMjj4YCs28RJMZOnC8LPC9vuTPYZDFsZoVEmzl+9d/Hw2jiWHrgwRDPpIZEkIIIYSoueMlTi6avpR3lu+q9X1VFgupqspd7//GlM/XBZa5PF6ufXMFz32bHbTu9iNFTHxlCd9tPIRDlw2KlBkyytZEmxnanVfMxFeWRHy8VZI9ZF/hT6wCNosStsyvzOXlb5+u4673fsPrVaMqS9OXxt3/yVreXLKTNxbvCBsbBVqHOX3DhPgqB0OSGWpQZJ4hIYQQQoia+/ei7azec5xHv9pY6/tSDRtMl9t7tJTZ6w7ywcq9gczI0m25LP49lxk/bg9a9+4PV7N+fz63zVoVlA1yRgiGCgwCFINu1YYe/GI96/cbj3d64vwTuGxoeyy67l4Ry+R0wZDXqwYdd5HDxUe/7mX2+oNsPFAQVZncQV1mCOCpbzYZBkKgZYb0qYREm9Zl4qkL+wWt5w/sbju9K70zkwPLcyUz1LBIZkiIGlBVcBbX7ZerRPu3CiUSr732Gu3atcMb0ib1ggsu4KabbmL79u1ccMEFZGRkkJSUxEknncT3338fs9O0fv16zjrrLOLj40lPT+fWW2+lqKgo8PiiRYsYNmwYiYmJpKamMmrUKHbv3g3A2rVrOfPMM0lOTiYlJYUhQ4bw66+/xuzYRC0zeo/4f4dr+yvK90hdvz+mTp1K//79SUxMpEOHDtx5551B7weApUuXcsYZZ5CQkEBaWhrjxo3j2LFjAHi9Xl544QVOPPFE4uPj6dixI08//XS1j0fETqSJO2tDZVMAeXS//6VOj2+b8mX61tyH8ssDAX1JmcttvBN/6do5J2Ry7oC2AERYNUxuoXFW5KLBWVw3ohPtUuP59eHRDGzfAjDODAFBY3aKnO6gLNbxkvJtduQWGWaG/nxWd7KfOod/XDFQ249BOV4klpBWzHFW7ViuPbkT798yPLD8wkHt+PXh0TxwTm++vGsUY/tmAA1nzJC01vaRYEiIGnCVwDPt6mx3CpDq/+HBA2BLjGq7yy67jD/96U/88MMPnH322QAcPXqUuXPnMmfOHIqKipgwYQJPP/00drudd955h4kTJ7JlyxY6duxYo2MuLi5m3LhxjBgxgl9++YXDhw9z8803M2nSJN5++23cbjcXXnght9xyCx988AFOp5OVK1cGBqNec801DB48mH//+9+YzWbWrFmD1Wqt0TGJOhTyHgn6Ha5tUb5H6vr9oSgK//znP+nSpQs7duzgzjvv5K9//SvTp08HYM2aNZx99tncdNNNvPzyy1gsFn744Qc8Hu2CbsqUKbz++us8/fTTjB49mpycHLKzsyvapagzdThJaWXBkC64L3F6SE3Q2nH75RU5SWipXQ6XRRgnFCkz5M/WdGqVwJFCh29/0R22O8LcRW1S7IG/+6kJNtISbUB0AWZhWXAwlF+qC4aOFGM2mEemfVoCcVYzbZLjojtwndASPX3zhPapCYHvE2zmQHYozmqmcyvt71FDGTMkwZCPzDMkRNOXlpbG+PHjef/99wMXe59++imtWrXizDPPRFEUBg4cGFj/qaee4osvvuDrr79m0qRJNdr3+++/T1lZGe+88w6JidoHwb/+9S8mTpzI//3f/2G1WsnPz+e8886jW7duAPTp0yew/Z49e/jLX/5C797afBo9evSo0fEIEaqu3x/33HNP4PvOnTvz97//ndtvvz0QDD3//PMMHTo08DPACSecAEBhYSEvv/wy//znP7n88stJSUmhR48enHLKKdV56Y1OfomLpDiL4cVtdXi9KsUx6IJ2rNhJWqKtwmSkqqrkl7pITbBFtc7RYicFpS46pScYdiqrrIGCPsAp8WWGihzlLza3yEHbFnEUOz1BmRN9MHS4oMy3vRvFVD5Oxp+tSYmzku/LwnhUKCh10UIxYzFHLsCKlNGKC2mIkByn3fQyatZQ5vIEBTzHip1B2RZ9ZmhrTiGpCeE30Oy+bE5Vx/tAeGZIz58l0p47ONxI9wV4DWXMkARDPpIZEqIGrAna3ec64vV6KSgsJCU5GcWaUPkGOtdccw233HIL06dPx263895773HllVeiKApFRUU8/vjjzJ49m4MHD+J2uyktLWXPnj01PubNmzczcODAQCAEMGrUKLxeL1u2bOG0007jhhtuYNy4cYwZM4bRo0dz+eWX07atVnoxefJkbr75ZmbNmsXo0aO57LLLAkGTaARC3iNBv8O1PWi1Cu+Runx/fP/99zz77LNkZ2dTUFCA2+2mrKyMkpISEhISWLNmDZdddpnhtps3b8bhcASCtuZkd14xp7+wiBFd0/ng1pNj8pyTPlzL/M0W+p5UwKBO6dV6Dv8g+2cu6l9hMHTvR2v4cs0BPrtjJEM6pRmuc9/Ha/l89X5eumwgf/tsHW6vypTxvbntdO1vnn7+nMpyUPoAx18mpx9/k1fk5KLpy8LG7+jbUt/x3m/89ZxezFi0HRVY8+hYzIop8DzJcZZAluRwmYkhz/zAKd1b8e7Nw4kkUmbIbg3+e5Acp12q+8cn6V/7wfwyvll3MPDzeSENGY7rAqVvNxwy3p8v+KpqJzjQxgxFou9yZzUHX2On+7JEuQ2kTE7GDPnog6HQSaqEEJUwmbQynLr8siZo/1bxRsbEiRNRVZXZs2ezd+9eFi9ezDXXXAPA/fffzxdffMEzzzzD4sWLWbNmDf3798fprJs/2G+99RbLly9n5MiRfPTRR/Ts2ZOff/4ZgMcff5yNGzdy7rnnsnDhQvr27csXX3xRJ8clYsDoPeL/Ha7tryq8R+rq/bFr1y7OO+88BgwYwGeffcaqVat49dVXAQLPFx8fH3H7ih5r6j5dtQ8on8QzFuZvPgzAuyv2Vvs5/IPsH/xifYXZmi/XaDcFQpsX6H2+ej8A932yFrcvhbLxQPnkom5dWqVqmSEteNEHQ7lFDsNGBqHttJ+fu4WCMjeFZW6O+i7i/WOGkuMsgcDglyPav0u25VZ4XB6P8XGHZobatdDK13b7JmV1RdjOSH5J5e9NfwYnwVr1/EiFwZAuqAtNOLRKspESZwka71SfGsZRNAD6/6fKBuMJIRqvuLg4Lr74Yt577z0++OADevXqxYknnghog7VvuOEGLrroIvr3709mZia7du2KyX779OnD2rVrKS4uDixbunQpiqLQq1evwLLBgwczZcoUli1bRr9+/Xj//fcDj/Xs2ZN7772XefPmcfHFF/PWW2/F5NiE8Kur98eqVavwer289NJLnHzyyfTs2ZMDB4KzywMGDGDBggWG2/fo0YP4+PiIjzdlVbkYriqLue6qZDxVvNiKVMJW2dPotytxhWeG9h8vDdsGKp6Txx8M+cfxJNmtFQYGRtwRDlzfqhqgl2++oS2HCoHI45eM6DNDkfj3F22Z3MPnlpdvV1SmqQ90Qlc7o1cb1j0+jtevGxrVPmubBEM++qg1Uj95IUTTcM011zB79mxmzpwZuOsN2gXW559/zpo1a1i7di1XX311WGetmuwzLi6O66+/ng0bNvDDDz/wpz/9iWuvvZaMjAx27tzJlClTWL58Obt372bevHn8/vvv9OnTh9LSUiZNmsSiRYvYvXs3S5cu5ZdffgkaUyRErNTF+6N79+64XC5eeeUVduzYwaxZs5gxY0bQOlOmTOGXX37hzjvvZN26dWRnZ/Pvf/+b3Nxc4uLi+Nvf/sYDDzzAhx9+yPbt2/n555958803a/TaGwN3LV6jWGM0BimaMCdSMBBJmdu4uUFl3RLL3EZlcsFjaYxEmmgVygf++59HXyYXzXN5vGrEjFZcSJlcrwytFfW2I0W4PV5cFRxXKP2YoUj8wVC0ZXIp8eXjjirKyunHdykNfGC+BEM++pLtqt6tEEI0LmeddRYtW7Zky5YtXH311YHlU6dOJS0tjZEjRzJx4kTGjRsXuCteUwkJCXz33XccPXqUk046iUsvvZSzzz6bf/3rX4HHs7OzueSSS+jZsye33nord911F7fddhtms5m8vDyuu+46evbsyeWXX8748eN54oknYnJsQujVxftj4MCBTJ06lf/7v/+jX79+vPfeezz77LNB6/Ts2ZN58+axdu1ahg0bxogRI/jqq6+wWLRynkceeYTJkyfzzDPPcMIJJ3DFFVdw+PDh6r/wRsIoiPB6Vb5dfzBowky9jQfyWbotl2/XH+RAhEwIVHynP1RukYNv1h0wDBr018iRhh74u7wdLXbyv7UHKszEADh0GR5HUKe38Of/ceuRQCbFoSuTO3C8lK/W7A+a3+a7jTmG+6soA/P+yj1s2J/PjiNapj85zoKtgqyaPwgrP35P1Jmh9mnxJNjMON1eduWVVOmGfXSZIV8DBWuUwVBceTAU7agSo8YXDYk0UPDRZ4aqerdCCNG4KIoSVpIDWkerhQsXBi276667gn6uSllQ6EVA//79w57fLyMjI+IYIJvNxgcffBD1foWoibp6f9x7773ce++9QcuuvfbaoJ9PP/10li5dGvE4H3zwQSZNmkRKSkrtN6JoIIwG3n+yai9/+2w9cVaF7KfGhz1+7j/LB9bbLApb/x6+DlBh97NQl/9nOTuOFHPP6B7cM7pn0GP6iVDdXjVsAD2U33i+buYKNuwv4I4zuvG3c3pH3F+kzJAjZO6c7EMFXD9zJQC7njs3KDP09JzNUV3A28xKUBAV6pt1B4MaF7RMtBmWybk9XixmhRJXcCe4MlfkDE9oZkhRTPRok8TafflsO1zICe1aVP4CfPKjCYZ8Y5QUxUScVal0YlZ/QwfQMkMndkrjwLqDhv/Hfu3TGvYYv+bxlyMK+qhVMkNCCCGEaIjcBpmQn7Zqg/Uru5CF8JItfaahKmVy/qzIt+vDu5TpA45I5Wb+a60N+7XGCF/6miZEEpwZKv8+dCLR9fuCmyHoz0m0mQy7VYl6bM5VwzrQtkW8YZmcP4ArCckMlTjdFDuNM2GhDRQAMn1NFI4UOauUGTJqoHDdiE5cNqR9+f50GaEEXQvss3q3MT4+XbDmVVWeuqAft53WlTl/PjVs3Zk3DOX+sT05o2frqI+5PlQrGHr11Vfp3LkzcXFxDB8+nJUrV1a4/rRp0+jVqxfx8fF06NCBe++9l7Kysgq3qU+R2h0KIYTfe++9R1JSkuGXfy4UIZoreX/UHn31ij/7XFEVUmU3ePUX6tWZt8jfdCHSMUS6eA+twqnsOMsilMmVhQRbjpAMUmiwpHf/2J6Gy+0WJeh5KvLkBf0A485q/n2HlskdraCltN2gXM0/YWluoaNq3eQMMkNPnH9C0LgffXCjHzd07+ieDGgfnoXSt8xWVUhLtDFlQh96+MY26Z3VO4NJZ/VoemVyH330EZMnT2bGjBkMHz6cadOmMW7cOLZs2UKbNuFR5Pvvv88DDzzAzJkzGTlyJFu3buWGG27AZDIxderUmLyIWPDq3oSSGRJCVOb8889n+HDjOSSs1vCJ7YRoTuT9UXv0DRRcHhWbxVThXImVZRJCL9Sryh9AWZXybIo+0ImUYfFWORjSjxPSBUMhwY7+58IyV1gZnd6JEeY58njVqIMhfxBkqyAYCs0MHSl0hK3rZ9Ru2j8vT16xo8LGDqGMxgyFBib64EY/big9yWb4f6I/vqZyuVzlYGjq1Knccsst3HjjjQDMmDEj0HXmgQceCFt/2bJljBo1KjAIs3Pnzlx11VWsWLGihoceW/qOGEYpaCGE0EtOTiY5OfxOmBBC3h+1yRUSaNgsSljrYr3KLur9c+9AeNvu//jmAvJPdmokEAyZTfiv+Usc5c+pv3jXj6MMzQzlFTt59Ydt3HVmd8P9HCoo49GvNnD32T24/+O1geVlLg+qqgYu8vUd1ArL3GGZI72MlDjD5cdKXBwrOR5xOyNGZXL3fLiGaVcOCjrHUHEwFNpAAbR5eUCbILYqrbWjKQvUBzf6/5OWicbBkH5RU5mXs0rBkNPpZNWqVUyZMiWwTFEURo8ezfLlyw23GTlyJO+++y4rV65k2LBh7Nixgzlz5oQNktRzOBw4HOW/KAUFWj2py+XC5ap8MFgo/zYVbevRlcaVOZ24XHLnKlQ051FUrimcR7fbjaqqeDyemLWergr/H2BVVetl/02F/zx6vV5UVcXtdof9Xjbm39P61lQuFJqrhvr/F5QZcnvBXnG3rsoyQ/qshX7dYoebZ7/NBuCCQVmBcSuhzL59Wy0K/mgoT1cGpg+w9N8bXWi/8N0WLj4xK+KxvrN8Nx//ujcoS+RVg5s05BWXXz8WOdwVlsmlJdjon9XCcNLVaPxlXPkccUZlcr/uPsafP1jNzad2DVq+91hJxOcMbaAAkJ7oywxVMGbIZIoc/MRbzZS6PJzQLiXsMX3ba33QFmc1G/4fZaTYA99XNuFtY1GlYCg3NxePx0NGRkbQ8oyMDLKzsw23ufrqq8nNzeWUU04JfNjefvvtPPjggxH38+yzzxq2jJ03bx4JCQlVOeQg8+fPj/hYbq4Z0H4hFv7wI5nV302TV9F5FNFrzOfRZDLRtm1bjh49Wq93fwsLjeeHEFVz7NgxiouLWbhwYdgFYElJ5A9tYcxfBlZSUkJ8fMPuoiQi8//uN7SyPn2mx39hXNGQDKOLZ5fHG7h4L3UZB0MFurl4th0uihwM+S6mPbpARx+Q6J9Tn9WI1Ln3WHHFN2CMmkSUuTyB15NbVB6IFZS5IgZDaQlW0hKszPrjMC6evowducWG64Xql5XCq1efyP5jpZzcNT2wPFI3tQ0HCoLmNQJYty9y8GWUGUr3ZYZyix0Rg6Gv7zqF57/LZvHvuWGP/eHkjpzesw39syruRBdazqcPhhbedzqlLg+pCbbAsmZbJldVixYt4plnnmH69OkMHz6cbdu2cffdd/PUU0/xyCOPGG4zZcoUJk+eHPi5oKCADh06MHbsWFJSwqPayrhcLubPn8+YMWMi/lGbdWAlFB4HYNQpp9IrU9L7oaI5j6JyTeU85uTkUFBQQFxcHAkJCXU6QFJVVYqLi0lMTGzwAzMbMq/Xy7FjxygsLKRt27YMGjQobB1/Zl5Ez2w2k5qaGpjzxuj94fV6cTqdlJWVNZuW0LWhNs6jqqqUlJRw+PBhUlNTMZujm3+lrpQ4whsJVDRmyGiMSYnTQ4t47XwV60vadBfahWXly7fkFHJKj1aGz+9voKBvYZ2nC0gitcGONHlsRc0FIilzeUmO8++7PBArLHNH7LDXtkU8JpOJ1AQbZ/Vuw44lO6Pa12k9WtMpPZFO6YlByyNNumo2mYLOJVQ9GAoqk4tQ9pfRws7oPhmGwVC81Rzx/08vdPyYPmDt2jopbP1mmRlq1aoVZrOZnJzgCapycnLIzMw03OaRRx7h2muv5eabbwa0eTaKi4u59dZbeeihhwz/eNntdux2e9hyq9Vao4vHirZX0f0hUcyN+iK1ttX0/0FoGvt5zMrKwmw2k5sb/oe3tqmqSmlpKfHx8RIM1YA/qGzbti1ZWVmG57Ix/47WJ/9nYqRJQOV3ODZq8zympqZGvLapT/o5a/xZgorGDBllEkqdHlr4OorpL4D1E5jqsxlbDwVn4fUZA8VkwuNVg0rgSoKeM1LjA69hKaI+qxQtffZHX6JXWOaOOJmrP9sCkQMZI/qOa3pGDRQALEp4MFTR/D9xRg0UfGVy+aWuiC257WYz8RGOzahDnZGqdvhrKqoUDNlsNoYMGcKCBQu48MILAe2uzIIFC5g0aZLhNiUlJWEBj/8uS0Oqx9VHt83lP1+ImvCXyrVp06bOx5W4XC5++uknTjvtNLlYrwG3283ChQsZNGiQXJDHWGXvD/kdjo2qnMcSp5s/vf8bQzu15I4Ig/T9rFarYUbopXlbmL3+IF/cMYoWCTX/f9uTV8I1b/7MH0d14YZRXThe4uTify/j3P5tuW9sL8Nt9IHGWS/9SIeW8fTStTX2eFVueGslNrPCZUPbc/u7vxk8h3Zxvu1wEXe8V/64fiJQ/QV8dk4h//lxO++u2M1Ht44ImnjTopgqHJfz9OzNrN+Xz0ld0vj7hf2DjsGouYO+zC1aK3ce5fL/LOcv43oFZaXu/2RtxG3aJJeX/VUlGIq3GV86R8wMmcODoYoYTXzbIt6KRTHh9qrk5BtPTWO3KhEDtdBsU7R/7SubaqZZZoYAJk+ezPXXX8/QoUMZNmwY06ZNo7i4ONBd7rrrriMrK4tnn30WgIkTJzJ16lQGDx4cKJN75JFHmDhxYoNKPevjn0h1rEKIcGazuc7fy2azGbfbTVxcnFxI1oDL5WpQN6WaokjvD/kdjo2qnMfP1+5h6a5Clu4q5N7x/aq1v1cWbgPg7WW7uHt0j2o9h94zczaz92gpj/9vEzeM6sLaffnsOFLMnPUHIwZDoaVMe4+W4tCVgu05WhIolVqQbZyZ9AdUD36+Pmh5pDK5/cdKA80UXv7+d+7Tzc9jMlUcDK3afQyApdvyOHi8tPx1uDxhY1QguMwtWvf5gp7JH0cOfgAuPjGLeKuZL1bv5+6zy///7AYTnUYSKeAwaqAA/syQdkOkRbw1kBXq3iaJm0Z14aEv1wcaH5zctaXhcyiKiZaJNg4XOjiQX2q4js2sBLXG1gttynDjKV145+fdXDQouFnFv64ezL0freHFywYC8I8rBnH9zJVMGd8naL27zuzGqz9s54Fzgpc3VlUOhq644gqOHDnCo48+yqFDhxg0aBBz584NNFXYs2dPUCbo4YcfxmQy8fDDD7N//35at27NxIkTefrpp2P3KmJAlcyQEEII0WR5Yth5srIObdEKbZNc6svYVHRT1iiA0K8dzbxB/qYJhwuDswyuCMHQUV3pWpk7OIhxur2BDI/NrNAiwRqxdXRuSJe5AoNysdxqBEPRmH7NiYzvp5U9Pjqxb1AAFCmrc0av1izaciRoWVWDIUU3Zuj+sT05d0A7XB4v6Yk2LGaFS4ZkYVUUjhQ5aJ0UPkTELz3JzuFCB4ciZIYUxRTxGOJCgr2s1HjWPz42rLTvvAHtGNM3I3BuRnZrxYYnxoUFi38Z15s/n92jSkFkQ1atBgqTJk2KWBa3aNGi4B1YLDz22GM89thj1dlVnQmeZ0ha9QohhBDCmEpsbpqGlisV+5ojVDTfoVGwo79uKXZWXpLlD2ZCgy5XhDFDobGZfh8OtyeQGbJbFXpnJkcMhkKzPkbjg6pTJheN5DhLoBw49CI+UjBklGmJlH2J9BwWxUSRr0lFUpyFlom2oMf9xxJpziM/fxOFgxGCIShvZgHQtkVcYF27QbvuSIFM6PJo12vMpIWNj/6GkZTJCSGEECKS0OrSwwVlHNNlPY4WO8OyLkcKHRwvCb7QDx2qV+ILKiJNrOn2eA0f03dMyy+pfAxnqVObf+fA8eCSq/3HSgMttSsa51Iakhny7z/OaiY95GJfLy8k0Fm953jYOgsjlPbVVKSsCQRPPKqnGHSmsEZYN1IDhSKHm98Paw0oku3VL4n1n9c1e49HXEf/GtvqWqGHZoZEMAmGfKSBghBCCCGiob9KyC91MeyZBZz10iJUVUVVVU5//geGPb0gMD6k2OHmpKe/Z9CT80PG6QVfbAfK5CIEQyURxubo5woqKKs8GCpxeth+pCgs47Mzr4Shf/8eIJDNCKWqwaV6Drc30FbbblFIr6DUK7QE7u+zN1d6rNXRzmBOpIpKGyMFQ60MAjtPhKyd1WLclqCgzE1Ogfa69Y0nqqqi8+qXqGvuoM80ReoyJzS1Ps9QY6FKAwUhhBBCREF/A9V/p/5Yidb22G5RKPQFEr/tPsaZvdsEZWCcHm+gxCgsM+QLMlwRLrjLohgPVFHbZv1+CkqNgx3/PDaRgioVwsYM+cvk4qzmsDIwvYpK4E7v2Zoftx4JW94qyRZxuy/vGsXl/1keOGabReHkruk8ef4JPPr1Ri4f2p4Dx0tZvec4I3QTpIaKFAzdM7onu/JKuGxoe3IKHKzcmcdpPVsbrhspM6SXHFeDzFBS8Hm9aHAWx0qcKCYTo7prcwj1aZvM5UPbk5ESx7AuLdlztIQ2yXaGdEqr9n6bAwmGfIIzQzJmSAghhGhSYtk+Xher7DlaEvg+r8hBK90d/B25xZwJmHXlVg63LhgKedrSQDBkfB1i1Io6VKQgJ3Q//vl3+rZN4W/jenD926sCjzvd3ohlcqVON6Uu/Zghb6CbXZxVISU+8gX/0QhzCHVKT+C/Nw1j9rqD3PV+cCvwji0TDIOhj28bwaAOqfRok8TGA9rk0MsfOCuQQXnnpmERjyNUpPE+aYk2/qt7nj+e0iXic0Qqn9OrSWZI/3v157O6M9mg26DJZOL5SwcGfj61h3HgJoJJmZxPUAMFyQwJIYQQTVZNW8rrt9ZPSJpb5AgKZHbmFgFaRzE/fRvqyJkh46CnohbWfoVRlsn5syl2qxI2nqbE6Q48T1rIfEoFZe6wMjl/YBVnMZNSwQV/pAzPXl9AaTWHB6yd0xMNt/F3dfPPsaSYIC0hclaqIrYYTA8RXWaoJsFQ+WvrmZlcwZqiqiQY8tH/XZQxQ0IIIUTTor/MrulNT30wtSVHHww5gxocbD9c7Ntf+TKHy0v2oQI+WLkn6DlnLd8VKHHzqvDmkp1h43b0jRIiiapMzuUOHKfNrIRlRkqcnkBmqFNIMFJQ6uK1n3YEfna6Pby3QnstcVZzhRf8+iyanv+/wyhDE7p/P/84GH9g0DLRbtjwIBpG3daqqqIGDX5J9uoHQ/pAr7cEQzElZXI++sxQpFpdIYQQQjR+bo9KhA7JUdHfQN2ZWxz4Pq/IGci46B/TX1eUuTycM21x2HM+8tXGoJ+f+mYTa/Ye55WrBpdv6648MxRNA4VSpydQ2mazKGEZmRKnh2JfINa1VWJQB7NsXSZM2587MMlraoLVMJPTOtkesd02wMD2LbRjMQgohndtSWZKHIcKgrvz+TND/dpp27ZLrbg1dUWiyepUxhxFIGapwX5aJ5eXyUUKEEX1SGbIxxuUGZIxQ0IIIURT5a7G57y+akR/y1RfupZX5AgKfPzlY+6gYCj6ff9v7YGgn6Mpk4smM+TStei2W8xhWQ1tTJH2eN92KdEeLpPH9KRr6yT+ccVAurQqv2Af1CE14jYpcRam/2EIED7u5rmL+3Ny13Q+uX0ED4zvTaquZC/Bqt3PH9ktnUfP68tTF/SL+jhDRRozVF03jezEgxN6By2ryhgmI+3TEph6+UDevvGkqLJQInpyNn1kzJAQQgjRdOnH51Q0qWkk+gAqqAOt7rnyip1B4338gZFLt2002Z1Iogmkommg4HSrOFzl7bDDy+TcgWCof1YLw+c4xdfBzK9v2xS6tk4C4KLB7Tm1R/njQyvoZvaXc3qTlRoPBGdokuwWrhzWEYAOLRO4/fRu9G1bHpj5y+QUxcRNp3RhYAUBV2UidZOrruQ4C7ee1i3w88ldW0bsQlcVF5/YnjN6tanx84hgEgz5RPrDJoQQQojGT3+fszo3PfXXBir6G6jlAUpukSOoTM4fGLlDyuSqQv98jhiVyTmDMkNKWJlYiau8wYJ+vhq9ViGtnuNCxt3oxwf5gyQjybpxNPqMh1HZWYe0hMD3sczmxDozFJq5SbDJqJSGTIIhn+AxQ1ImJ4QQQjQlXl0AFKlRktvj5Z4PVzNr+a6g5bvzirnx7V8CP/svGVRVDSqLywtpoFAeDJUvO15SebCit2bvcW6b9SvzNh6KKjO071hppeu43N6guXlCxwzpW29HChRaJgZPAhoXMghLP5bKWUFLcH3DBZtu4lKLQTDUMT0hbFks1LC5YJjQQE4mPW3YJBjy0f9hjKaPvxBCiIbl1VdfpXPnzsTFxTF8+HBWrlwZcV2Xy8WTTz5Jt27diIuLY+DAgcydO7cOj1bUNX02KNJNz7X78vlyzQGen7slqGPcnz5YzcqdRwM/+x8LDaqOlThx6a4hvKq2jku3XkWNBIzc98kavtuYw62zVlU5qxSJy+MNXOvYDDJDxQ53IMizWxSuPblT2HO0iLcGBVGhwdAtp3YF4OLBWQzsEFxq1zOjPFOkn4hU3+LaKDM0oX9bANq1qH6zBCP6OXxqokW8Ftid7isR9DeGuOqkjjF5flE7JG/no/97JsGQEEI0Lh999BGTJ09mxowZDB8+nGnTpjFu3Di2bNlCmzbhNfYPP/ww7777Lq+//jq9e/fmu+++46KLLmLZsmUMHjzYYA+isdM3R4qUGcot0gKVQoebA/llgbEsoS2h/YFVaLldidMT1pHW5fEGZYb8+4jW3qPlmZ6aBEPnDWjL4I5pPPXNJq1Mzl1eJhda1qVvwmCzKDw6sS9XnNSBP3+4mh1HtIxPUpwFm1nB5fHNMRRSJnfN8I4M6pBKz4xkbBaFhfedTnKclZyCMvYdK+X2d7VJXvWZIWslmaEurRJZeN/p1Z5PKJJ4m5llD5yFRTEx7JkFQPXm6F1476l8Nmc+PXzB3ge3nszeo6X0klbYDZpkhnz0d4AqSucKIYRoeKZOncott9zCjTfeSN++fZkxYwYJCQnMnDnTcP1Zs2bx4IMPMmHCBLp27codd9zBhAkTeOmll+r4yEVd0QcukbrJ6QMV/WSqSsiVsX8MkFEw5PQEBywujzcoQKpqZkivJjdrs9LiyUjRMiBOd3BmKLRM7lhJ+eSo/m5z/bJa0FqXQUmOs2DXZYPiLMGZIZPJRL+sFoEyu66tk2idbKdfVgtaxFuDnsdPH5SZIkQjXVsnkZYY22AIoF1qPG1046PM1YiGUuKtZMSX/5xgs0gg1AhIZsjHK8GQEEI0Sk6nk1WrVjFlypTAMkVRGD16NMuXLzfcxuFwEBcXXGoTHx/PkiVLIq7vcJRfxBYUFABauZ3LVbUxIP7t9P+K6qnKeXTqsiplDuP/t8P55VmYjfuPc0o3rQta6GWxw+XG5XJRGtKsoNTpptQRsszhxKnb1+GQ+XKq4lhx9QMpt9uD2df4wen2UOI7TosJVG9wAJenz1553bhc2hloqW9tbTEFBVFWsynq32ezqfw6K85c/v+nqOXHoapqvb4/FCX61+Mn7+vYiOY8xvIcSzDko7+5E3pXRwghRMOVm5uLx+MhIyMjaHlGRgbZ2dmG24wbN46pU6dy2mmn0a1bNxYsWMDnn3+OJ8Lf/2effZYnnngibPm8efNISKj+oO758+dXe1tRLprzmL1XwV8Qs+inxWw3aHD2207dOqu30KFoMwBOpxl9SLRn337mzNlLgRP0l1IlTjcrf/0NKM+SzJ33Pb/nmwLLth84Qnh4FZ1Vm3dQ3aKe7Tt2YsnbAZhZvTef1XvzAdi5bSvzS7cEvY7sHXsABYtJ5dtvvw0sL8otPz+b1v2G26EEXsvBfXuYM2dXVMeyu4jA/hYvnI+/Is7pKV9eUlrKnDlzqvNSa0jbv1n1VHv/8r6OjYrOY0lJScTHqkqCIR/JDAkhRPPx8ssvc8stt9C7d29MJhPdunXjxhtvjFhWN2XKFCZPnhz4uaCggA4dOjB27FhSUqKflNLP5XIxf/58xowZg9VqrXwDYagq5zH7+99h304ATh45KjC4Xe+7j9bCoRwAii0tmDBhBABPb/iRQld5tqRVRiYTJgziYH4ZrPopsFzFRPc+/eH3TYFlp59xJvadR2HbRu2YlTigehkeNSEN8vI5vWcr1u/PJ95qZv/x6DJNHTt1ZmTv1vwne1XQ8gH9+jJmaDsGbV3Amjwt0Elo0QryjhJvtzJhwrjAutt/2M7inO0AnH3qSBbkbSQvpwiA3j26MmFsz6iOxe3xMjd3BW1bxHHeueVj9Dxelb+s1C6AbfY4Jkw4ParniyVP+4M8NTubV68axEmdI8+PZETe17ERzXn0Z+djQYIhH1UaKAghRKPUqlUrzGYzOTk5QctzcnLIzMw03KZ169Z8+eWXlJWVkZeXR7t27XjggQfo2rWr4fp2ux27PbzjlNVqrdFFT023F5pozqOqz6iYFMP1j+raXm/PLcakmLGYlbAxQ15V26dJ0da3WZTAjdRCZ3B2UTWZg/adW+ykug74Ap9hXdJ5+8Zh/PvH7Tw/d0vg8Xf/OJw/vLnCeGOTiYS48LE28Xbt3N3Y08v+lF48/93vHPdN3Gq3BJ+nNinlA2LSkuJI0Y39SbBH/7tstcLsP58aNi5Iv7X/HNe1i4d05KITO0QcsxQNeV/HRkXnMZbnVxoo+EhmSAghGiebzcaQIUNYsGBBYJnX62XBggWMGDGiwm3j4uLIysrC7Xbz2WefccEFF9T24Yp6ou8mF2nS1dyi8kDF6fayK08rxQltbOb0NUTwt+i2mxXsvkYB+k5s2r68Qa21I3Wyi8ZhX/MFu0XBZDKFdVzLrKDltFdVw7rGAUFttRN8DRH8r8Ee0hShpa5xQXKcNagtdmhr7cpUFmyosZ78pwpqEgiJxkeCIZ+GEgzlFTnYdriw8hWFEEIETJ48mddff53//ve/bN68mTvuuIPi4mJuvPFGAK677rqgBgsrVqzg888/Z8eOHSxevJhzzjkHr9fLX//61/p6CcJAbpGDjQfy8XpVVu0+SonTHfR4idPNzkLYnVfC7rxiHG4Pv+w6GtTK2s8dEpAcyi9ji65jXG6Rg22HtZKvJLtWOLM1R3tcCQk6XG4vq3Yf47gvaLCYTST4JtYsCAmGnG7V8Hhqwh94mJXgy7jWFcyX4/ES1jUOCOoI558cdP9xrZFE6ISr8bp1k+MsgfMEEBdhctbq8tRjMCSaFymT8wluoFB/wdCQv38PwI9/OYNO6Yn1dhxCCNGYXHHFFRw5coRHH32UQ4cOMWjQIObOnRtoqrBnzx4U3YVjWVkZDz/8MDt27CApKYkJEyYwa9YsUlNT6+kVCCNDfZ+J1wzvyHsr9nBS5zQ+uX1k4PGb/vsbq/ZYmLZB6wJ47oC2zF53kLvO7MZfxvUOei5PyKSrJz+rZRKX/O1M2qclcMe75WNphndpyYLsw/yeUwT9w+ecWb4jj0v+vSwwMajFrE1ceqzExfGS8MyQ2xPbC3t/MBSaGQoNXvQyU+IC2augbXSZoWS7NeJjAOlJ5Zkhu0UJaotd1cxQZbw1yKAJURUSDPno07ENYczQmr3HJRgSQogqmDRpEpMmTTJ8bNGiRUE/n3766WzatMlwXdHwvLdiDwC/7DoWtHzVnuNBP89edxCA6Yu2hwVDoZkhv9V7jpOREseavdpzXXJie9J8LaT9majQMUOhz2NVTIGsSmiZnMvjxRVhXqPKZKTYySkIb7bgn+DUHBIMWcwmXrpsICt25uFV4dQerUiwWfh2w0FuOa2L4RxHdt1kqSO7tYz4GED/rBbccmoX2qXGYzKZalQmVxlJDIm6IsGQj7eBNVAwqusVQgghROWMJsz0eIxvepY6PezKLcblUUm0mXnxsgH8n68pgX+y1EjBkJ/FrATK5EIzQ1qZXPWu7Pu1a0FOweGw5f4JTkMzQxbFxCVD2nPJkPZBy8f01TKkVnP43Cx23fVGot3Csxf3Z8rn64HwzJDJZOKhc/sGfg7ODEmZnGic5IrbpyGMGdLfqQr9AySEEEKI6IRmTCA4M1Somyy1xOlmi29sUM/MZEym8slE3b6MTmXj6S1mU2A8jVEDheqOGerQ0ngOq/IxQ8GTnlY28N+ojC40+6MPcEIfCxW8bozL5CQYEnVErrjRSuT07zmnu34mXS3TzY5tjfFARCGEEKK5cLi9zFq+K2iZvptcQWl5I4bCMnegkULvzGQALL7xZS6Pyocr97DjSHGF+7MqCom+ZgLGZXLVu7Bvl2rcHc4fpFjM+mCo8usG425ywUGMvilCZTdmg4KhGF+3yJAhUVfkipvwutT6aqBQqguGQlPfQgghRHNS0wH0j3y1kdV7yscY6TNDBbrMUF6xk525WrDTrXUSUB5kbDtcyAO+krGKWMzlY4aKHMEd71weNayddlZqPNEY0bWV4fJ4g25y0Vw3GDZQsIRmhqwRHwulb7gQ+zFDEg2JuiHBEOGpWIernoIh3URtNZmHQAghhGjsYnFjcv3+/MD3nqAyufKAJa/YSbEvgEnxBQL+Mjl/kFQZi1kJzNETyuXxBuYjykqN58EJvXno3D5B69x5RjfDbfu3b8Fr1w7hL+N6BS33Z2/0AVA0wYhRZig0QEoJyvZU/JxJ+jFDlaxbVXIZJOqKBEOEv+HqKzOkL5OTYEgIIURzFotmRv75ciAkM6QrZcstdFDiuxmZYPc3JtAuj44Wl0/CWhGrUj7PUCi3p7yBwiVD2nPrad2CMkMWxcQfTu4U8bnHnpDJsC7BXd785WnmKgZDRmOpapQZqsUGCjJmSNQV6SZH+Buuvhoo6MvkIs2OLYQQQjQHDt34XZtZCdyodHu8WKJsMqQf6+MJKpPTZ4YcgUDCH9D4M0PRfhRrZXLGl1ROjzfQiMHqC0b0jQlsFqXS8TbxIYGOPyMTnBmqXjASum99gFNZQJIirbWjo6pQlAPH98Cx3XDc91V0GDwu8LrB6wGv/3s3eNzl34d++R8zWyBzALQ/qfwrqXXtvhaPG3K3wqF1cHAd9BoPXU6t3X3WMgmGMBgzVEvB0P7jpeQWOhjYIdXw8eAyufpv7y2EEELUJa9X5fZ3V9EzI5krh3UILFcUwPcRWeLykBJlMLRoy2FGT/2RJy84IVCqBvD95pzA93lFTtIStclE462+IKOKHV2tutbaodweNdCi2/+8+sYEVrNSaQYmUd/UwKIEyteqmhkyEvpa9a+jsush/bp1PtbZ44Ky/JBAweP7Cl3mBtUTvgwTWOPBmqD9a0vU/ZwAFlulhwFoF5IleZiObKfdsRUoy7ZB4b7y4Cd/L7jLYn8OXMCuxdqXX2qn4OAos3/0ryPs+UshZxMcWgsH12rBz+FNwa/FbJVgqCkIvfPh9mqDHY3SyTUx6rmFAHw/+TS6t0kOe1wyQ0IIIZqzn3fkMW9TDvM25XDxiVmB5fqPxFKnJygjURGXR2Xb4SK+XnMgYvl5XrEzMKeN/+K+qhf2FsVEr8zwz3XtGMpba/szTvrgJyXeUunYHH3QoR/TY9E1UKjumJ1EmxnVW379oW/PXWGpoqOQFp5i4nBQho3UhGpecBuw4aKN6RjsXgYFB6BgP+Tv1/4tOKB9FeUAtXytpFjKAyN/kGTzf5+oBVjH92pBj6sYC3ASwC6D5zIpkJKlBSupHbWvlLZgtmv7MVu0fxULKFZQzOU/m/U/W33/msFZBPt/g32/wL5f4Uh2edZpw6fafs12aDvQFxwN1f5t0T68X3zpMTi0Xgt4/Fmf3K3aawxlS9KCrMwB0OW0mJ7y+iDBEMZpYKfbG+gME2srdh41DIZkzJAQQojmrExXGqe/ENdnKEqc0U1/0T4tntF9Mnh72S5fqVrkz1X/RKnlZXJVywyZFYVxJ2Ryw8jOvL1sFwCKSQvi9K21/UGWPvjp2SY5ECRFor8e0W+rv2lb2ZxAoVrEW1n8tzOxmBVc3uBzasFNBsfoVHQI1u2A/H3BXwX7oCwfC5AdB6pJwfRCspZZsSdpF8v+f/Xf233r+Jd53MEBTsF+frHvoLWpQDuQt6J4ISZFF0RYgoMIxVLx46pXy3I4i7UsiKtE+94fAHjd4CjQvio/ENTkTI56k0jrMhClZRdf0OMLflq014KaWMvsD0Ou174vy/cFR7/6AqRfoPQo7FupffklZWqBUasekPu7Fvwc32P8/ImttaCn7QDfvwMhrYsvXds0SDCEcU1wbQZD+vkN9IIyQ9WcrVoIIYRorILn/DPOSpQ4jT9DQ2WlxtMpPSHwXNHcZPR/7lsqCU5C+YOZcSdkBoKhRJuFQocbl0cNZIbM/jI5XWaoa+vESidL1Xeq0wdA+uOsLLukl0QJJ9oLSNk1D/L3oRzbzdCdv2B++xUo2M8W+0HMJhUOA59X/nwm1QuOfO2rMOrDMNTa95LKVCtx6R20bEpKO99Xlu7nLEhIr52Lco8rOEBylYDT969+mapqQU5aZ2jRHreqsGTOHCZMmIBirYXApzJxLaDbmdoXaMd3dEd5cLT/Vy37U3QIsr8J3z61ky/oGVge/CRnVj7rcCMnwRDGcxk4PB6gdn6R9TNf65U6y//we5rUyEEhhBCiYqGfjZEyQP7xtZXNQ2MxmwIZHlclmSG/BFt4Y4Jo+MfdGJXKuTxejvkyT4EGCrpgqHOrxKifH0KCoUgNFLxeKDwAR3fCsV2+L+37VfatpJsKoQz40PecQBbAcd/PJnCoFo5aWtO2Q3ftgl//ldIeWmRppWKuYnAUaSVbzqLy7w2XFWpBhn+ZomjPpQt2Jry9nQNqOsdJYtefz6v03NQKsxXiU7WvqnAZX9/VG5MJ0rtpXwOv0Ja5SrXxP/t+gbztkN7dF/j0h/i0+j3eeiLBEMFlcnaLgsPtDdyRcrg9Fd5tUVWV/FJXlWplCyIFQ1ImJ4QQohn696Lt/N/cbC4b0j6wLFIGyB8kVRbcmBUl0KhAm/g0PNOUEmcJ6ixXPmaoig0UfEFJy8Tya4ES32f61PlbA8uMGij4J3qNViAYcpWReHwrY5Rf6Wg6zFm5xfBukRb4HN8NHuO24Om+zY+TQmq7btCiPZ7kdmzaX0ifk8dgSevESf/KJpcURrRvzfs3nFzxAdmTta8Y2aTOBrQyQ1ELrPHQ8WTtSwDNIRjyuMHtqLBH4wvfbQG0ANqmC4Y+/mUvf/1sHZPO7M7wri05tUd4u8L3V+7hoS828MKlA7hsqNb55rc9x3j9px08cf4JtEmJ0w4jwmRvemXSQEEIIUQz9H9zswH4ZNW+wLIiR8XBkKuSOQEtiilQjuZ0ew3Lz3tnprBy11FAuwbwZ2yqWianX//+sT2Zs/4QJ7RLCXo9UF5OpygmLj4xi7wiJyd11uYQuu30rqzceZQnzj+ByR+vZfKYnmH7SaWQc9wr4YP/wPaF9HSX8ro//jrq+/JTLNpYlbTOvq8ukNaZCbP2skdtQ2abNnx/6+kAeF0udsyZQ+/eE8Bq5aErMvnXD9t48oJ+VToPsfD+zcN55KsNPHvxgDrft2iemn4wtH0h1vcv4zwUHGvjcNu0riDxiSlgTaBItXL2njJGWO2UYcdriueoxcKqWd+xJc/DVWY7e35cyic/9GHsyYPp0iqR5Tvy+PNZPejfvgUPfbEBgL98uo5LTmyv/YGbvgzQBic+d4n2Ztb/0Y4UDAW11q6niV+FEEKIhqDYEaFMzqV9hrrclWWGysvknB7jMUMp8eXl8AlWc2DsTlUbKOjL2Cad1YNJZ/XguW+zw9fTZZymXj4o6LEp4/sEvv9+8unlD+Tvg+zZvG99m2FKNpYSL2j3cPHYWrCxrCV71DakZfVk1ElDywOflCytQ1mIaDIvFw7O4sLBWZFXqEUju7diwX1n1Mu+RfPU9IMhlzbhmhkvCWoJOErAARRpDycBY/RVcCraWSkgaMhQsWrn2V+u5inP2agoLN2WyyPn9Q3aVdcH59A+rXxW6WKncaZHP/O1nrTWFkIIITTFlWSGtLG9kVkUUyAT44oQDOlbVlt143iqOmbIarC+UYe4qDJOqgpHtkD2/2DzN3BwDQAjfYe609yFLqdcAb3PZZe5C+dP/QmASV26M2pIr6iPWWnig+KFiFaTD4bWJ5/ONWWvE4+DeJODBBzE4+CFC7rTtYXC2p0H+HBpNvE4icdBgqmMBBzE4STBt35702H6KHv5u/Utxisr+Zv7VvY5WzPl8/Vh+9t3rDTwvf6PqUvXFUfGDAkhhBAVK4wQDJUGyuQq/pxUQsvkDD5X9RkgfXVGVSddNVrfKLsUsYW21wv7V2kBUPZsyNume9AEHU/m79u7Ms87lPQOvfjizFHafvOKA2vFVbG1dqznUhSisWrywdCOo6V4bCm0T3Gxo8TOLl9Hlw3xg+napx27HPv5wFOeCv6/S/rz09ZcRnZPJ9+r0q1jGnuPFdO76CtM3z/BKDayOP4hpluv44W8UYCJyWN60r1NEk/P3sz+4+XBUG6RI/C9Szdw0z+fQaiyCJkkIYQQoqmKdPOvpLIxQxVNCIo2f49N103OaD+dfa23IXheo8rm/QlllPExXKZvzOB2wq7FWvCzZQ4UHix/zGyDrmdA73Oh1wRIasMbD2jlbae3a1G+WlA3uapNB9K3bUqV1heiqWrywdAFg7IY3jmVefO/Z+iIk7j89ZUUOdz8+YPVFJS6wlqnX3FSR644qWPQsn5ZLYA7oMdY+OouTHuWc5dzOgOtP/I3161cN2IMqQk2HG4P9360NrBdXpHWyWXV7qPc+d5vgeVHi52oqho2r4BkhoQQQjQ3R4vLu55ZzaZAxqc4Qjc5/81Cp8HY2tevG0pKnIX5m3K47fSurN+fD2hZJHdIN7mbT+nCzad25SVdtze/qneTC1/fFpQZUmlvOkLG3tmw83dtYsyDa7S5agIbJEOPMdDnPOg+BuKCg5Uv7xrF12sOcM+YHobHqW/XXZH/TTqFL1bv5+7RPSpfWYhmoMkHQwDpiTZa2KBHRhJ3nNEt0D3u4S838Jdx0dfXkt4NbpgDK/+D+v0TnMJGFtmmYN3khSE3csFArTOM3WrmkS83kFesZYYunbE8qJmd26vicHvD7uJINzkhhBDNjf+zEoJL34oiNFDwt8gOnZR1SKc0xvTNAGB413SgPCAxmnT14ZBxv3o1zgwVHaFz3mLusSxioGk7A5XttDQVweKQDRNba5mfPhOhy2lgsUfcx6AOqQzqkBq0TJ8ZskeZGerfvgX927eofEUhmolmEQzpZfpaXftFamYQkaLAyXdg8mWJrHuWwzf3wqavUM5/hZtP7cqB46U8gpYZUlXVsKt3idMTFgzp73IZzYcghBBCNDX+KopQkRoo+D8qQ1trG42B0XeTq8pNxqqMGUqgjI6Fa2DpXG3cz4Hf4PgeRgOjdVdZDtWCq1VfkroOh6wTIWsIpPfQriuqST82OdrMkBAiWLMLhoZ1aRn4vm2LOPKrGgz5pXeDG2bDiv/AgidhxyKYPhLGPkXLAdcCWnanoNT4j3mxwx00ORsE3xGTzJAQQojmQD++Vi/SPEOfrtpLos0c9HkOYDbojmazaMuOFBrvI5LKusllcYRbLLM5WdlMD9M+zGtDP7NN5Cd14fv8LNZ4u7HW241stSPTzx7BaF/2KhbMuoxUVUv7hBCaZhcMdWiZwKw/DuPaN1dyrMQZsZlBVBQzjLgTeo6DL++EvT/DN/cQt+kretgv43dHKrnFxn+AS5zh6X99Ct8rwZAQQohmINLncKTMUG6Rk5fmb+WB8b2Dlhtlhmxm49Kxrq0SA9/ffEoX3liyk9F92gSWRZpnqBX53GX5kmvM32MzlX+OF9kzSOo6TMv2tDsR2g1i9W4H9731S9D2XVonhj5ljeiDtqpOFCuE0DS7YAhgcMc0AMpcXuZuPFTzJ0zvBjfOgRUzfFmiH/jS9DNPma/hSMFww02MBoa6dSl/yQwJIYRoDiI1SogUDPnlFJQF/WxYJmcJX/bMRf0Z3y8z8PNfzunFyV3TOblbesTnSqGYWyyzucM+D4tHa3qwxHMC73jGstrbnZvOGMEdZ3QL2ua0HiqvXzeUEqebXpnJFJS66dY6qcLXVFX646zqOCchhKZZBkOJNnNQx5qYUMww4i7oMQ6+upPEvSt4zvoGB+dupi1XcpD0oNVLDAaG6o9HuskJIYRoDkoNKiUgcgMFvzJX5WOGbAYZntF925CmK1O3W8xhpWv+wCIOB9eb53GH5WtSTcXggZzkftybdz7LvP0C6xuV3CuKKdDQobboS+OkTE6I6mmW7xyTyUSLeGvtPHmr7nDjt8zN+hNlqpW2R5Yyz/5Xxikrg1YzzAx5JTMkhBCieSmOEPRUlhlyuIK3M84MhV/mRBM0WPDwB/N8frTfyxTrB6SaitnqzYIr3mPO8FlBgRAYB0N1Qf+SpUxOiOpplsEQhN9RiinFzOF+NzPB+Szb7H1JNpXygvU1bJT/sSwxLJPTZYZimbUSQgghGqhSl3HQU+qqODPkCGmtbdhAwSAzVGFvBK8H1n1Mwmsn83frW2SYjrPX25rJzts5x/l/0Oc8bAYtrKvcmTZG9PMVRhrnJISoWLN950TqUhMrXVslsUNtx+2Wv3NQbUmKqYRTlPWBx43uhOmzQZIZEkII0RwYNRSKRlk0maGQAKFDy3iS4wwqQ1QVsufAjFPg81tQju/iiNqCR1w3cJbzJT73nobXd8k0vl9brGYTp/ZoxXUjOgFw15ndq/UaYqFXRjKJNjP92sncQUJUR7McMxSqfVo8+46VxvQ5u7XROsbsOFrGt+Zh3GSZy7nmn1noPRGIlBmSeYaEEEI0L9UOhtyVB0Ohy76ffHr4ejsXa82P9vnK2eNawKi7OW12Z0oJnpsQoGWijfWPj8NmVjCZ4IHxvUmw1d/l1Ow/n4Lbq4bNXSiEiE6zzQz1zkwGYGCHVMM0ek1lpsSRYDPjVeEbz8kAjFFWYUebXM4oM+SSzJAQQohmJlIDhco4omigEMpu0QUMB1bDrIvgv+dpgZA1AU6ZDHevhVPvMwyE/OKsZhTFhMlkqtdACLQJYiUQEqL6mm0wNOMPQ7hxVGdm/OHEWqmzNZlMdPXNJ7Ba7c4BtSUpplJO9ZXKVZ4ZkmBICCFE41Tm8nC4sKzyFTH+PIxqH1Fkhgx5PfDDs/DambB9IShWOOkW+PMaGP0YxKdV63iEEI1Tsw2GOrdK5LGJJ9C2RbzhPASx4J9PQEVhjkebb+hc888AFBvcCdM3UJDMkBBCiMbq7Jd+ZNjTCziYX3kJenXL5EK3M2qgEKboCLx7Mfz4HKBCv0vhT7/CuS9Ccu22wRZCNEzNNhjSq60OLF1blU+u5g+GRiu/YcdJiUEDB30AJJkhIYQQjdX+41oQtGLH0UrXraxrXCSh8/WZK2ktPcS0Bf5zKuxYpJXEXfQaXPompHWu1v6FEE2DNFCg9oIhfxMF0Erl9qvpZJnyOE1ZR4mzQ9j6+nmGJBgSQgjRGOnHAEUzp1/1M0PBNxUjZ4ZUbjbP4QHLB1DohVY94fJZ0KZ3tfYrhGhaJDOE8TwEseBv0gDhpXKhf/xVVcXlkcyQEEKIxi2v2BH43m4w6Wmo6jZQCM0oGY4ZKj3ODOs0Hra+h8Xk1cribvlBAiEhRIAEQ4C1lmZt7t4mOejn2b6ucqOV33A5ioMeCw1+3NJaWwghRCOUV+QMfO+q5MaeqqrVbqDgCpmcPCwYOrgWXjudc8y/4FAtPKXeDJe8AfYkhBDCT4IhwBbFnavq+uyOEYHv16jdOGRqTZKpjF6FK4LWC22YIJkhIYQQjZE+M+RyV3xjz+H2EquPu0AwpKqw6m14Ywwc28Veb2sudT7O5+ZxEE2TBSFEsyLBELU3ZghgSKeWbHxinO8nEz/HnwbAyaU/Ba0XGgxJNzkhhBCNUW5heWaosiqH6o4XMmJWTOAshi/vgP/dDR4H9DyHc51Ps17tilmp3mf9qT1a8cD43nx516iYHasQouGQYIjaGzPkl2ArnwxtU+pZAJzOKoqKCgPL9XMMgWSGhBBCNE65usyQ01PxZ1k0JXLRTh/Uumw3vH42rP0ATGYY/Thc+QEFaGVx1S2Jtygmbj+9G4M6pFZreyFEwybBEJCWaKvV5zfp0vI5yX3Zr7Ym0eSgcP23geWhtc/uSj5AhBBCiIZIP2Yo9EZfqMqaJ9gsCvFWc4XrAExUlvGHdTfAkc2QlAHX/w9OuRd02SBLNYOhqCdzFUI0ShIMAX86qzsndU7jmYv61/q+vJhYYj8FAEv2l4HloaUEkhkSQgjRGOUV6cYMhQRDBWUu/vzBahZm5wDw99mbK3yuOItCXAXBkA0Xj1ve5hXbv7B5S6DzqXDbYugcXtJmqWaZnCLjjIRo0iQYAlITbHxy+0iuHt6x1vflVVXW+0rl0vYtBGcJEJ4Jkm5yQgghGqO8Yl03uZDPtn/M38rXaw9w09u/UuRw8+PWIwAk2Y2nPYyzmiMGQ1kc4WPbE9xgmQfArx3/CNd9BckZQeud1rM1ADeO6lyl19ErQ+sIe/GJWVXaTgjRuMikq3VMVVVK0vuz51BrOnIEfp8HJ1wo3eSEEEI0Cbn61tohmaF9x0rLH9N1mnvtuiFc/Xpwl1XQgiGj8rahpmzesL1EqqmYY2oS97ru4ORuVzFUCQ+cXrt2CNmHChmQ1aJKr+PzO0ey40gx/bJSqrSdEKJxkcxQHfN6IaNFPLO92pxD2QveweNVwxsoqBIMCSGEaHxydWVyoVUPXt2NPv3nXOsku+Fz2S1KWJOj05W1zLI9R6qpmDXerpzneJpF3sERGy3EWc0M6pCKUsWxP4l2C/3btwga9yuEaHokGKpjKipd0hOZ7RkOQMe8JSxctyOslMAjDRSEEEI0Ml6vylFdmZwz5EafvgrCHxgpJrBE6OoaZzUHTX8xQfmZ160vEm9y8oNnIFc6H2E/rWP5EoQQzYwEQ3XM44VTerRig9qF3d42JJgctNi3KGyMkMwzJIQQorHJL3UFlXmHZYbU8MyQWTFhjpB9ibMqgZbYl5kX8Yr1FWwmD//znMytrvsoozyjZEIyOEKIqpNgqI6pqkq71HjAFCiVa7tvbnhmSIIhIYQQjUyebo4hCB8zZBQomRUT5ghtr/2ZoZvM3/KC9TXMJpX33Wdyt2sSrpBhzyryuSmEqDoJhuqY/0/1E+efwGyPLxg6/BN5R/OC1pPMkBBCiMZG3zwBKg6G/Fkis8mEJcJ4Hq/XyxVF7/KodRYA/3Gfy4Pum/HK5YsQIkbkr0kducbXtvvPZ/cA4PqRnRkw9BR2ejOweMv4+pO3AW2wKGilBr/nFNbLsQohhBDVkRcWDFVQJucfM6SYgubySfdNhG7Cy4U5/+LiwncBeN51Oc+6r4YI5XBSJieEqA4JhurI3y/sx4YnxjGoQ2pgWaLdGiiVO9f8M0DQfApXvPZznR6jEEI0Zq+++iqdO3cmLi6O4cOHs3LlygrXnzZtGr169SI+Pp4OHTpw7733UlZWVkdH2zTpO8lBeGbIbZQZUoIzQxazCTMenre8xmXubwB41HU90z0XEikQEkKI6pJgqI6YTKawSeUS7Rbm+LrKnamsIYEy4qzl/yX6jjxCCCEi++ijj5g8eTKPPfYYv/32GwMHDmTcuHEcPnzYcP3333+fBx54gMcee4zNmzfz5ptv8tFHH/Hggw/W8ZE3LXkhn1uhzYGCWmv7HjKbgscMxeHm9fh/cZnlJ9wo/DfjAd7xjKu9gxZCNGvVCoaqevft+PHj3HXXXbRt2xa73U7Pnj2ZM2dOtQ64KUmyW9ikdmKHN5M4k4uzld8izrQthBAisqlTp3LLLbdw44030rdvX2bMmEFCQgIzZ840XH/ZsmWMGjWKq6++ms6dOzN27FiuuuqqSj/PRMVKHO6gn53u4DI5t9e4TM7fTS6eMl5wP8NZ6gpcWNk/5j/8lnZOVPuWBgpCiOqocjBU1btvTqeTMWPGsGvXLj799FO2bNnC66+/TlZWVo0PvrFLtFvQd5U717yCtARb4PEW8dZ6OjIhhGg8nE4nq1atYvTo0YFliqIwevRoli9fbrjNyJEjWbVqVSD42bFjB3PmzGHChAl1csxNVZnbA0BynFYJEZoZ8hgEQxbFhFkxkUIxs2zPMcy7FqyJWK/9hE6jLseiSBGLEKL2WCpfJZj+7hvAjBkzmD17NjNnzuSBBx4IW3/mzJkcPXqUZcuWYbVqF/edO3eu2VE3EYl2LQs023Myf7J8yZnKGj62OJj1x2Fc+6bcnRRCiGjk5ubi8XjIyMgIWp6RkUF2drbhNldffTW5ubmccsopqKqK2+3m9ttvj1gm53A4cDjKx8MUFBQA4HK5cLlcVT5m/zbV2bYh82eGkuwWCsvcOFyeoNfo0QVHpQ6tpE4xgVpwkA9sf+cEZTeFJBJ/9aeo7U8ClwuLEl3Gx+v1NrnzWVea6u9jXZPzGBvRnMdYnuMqBUP+u29TpkwJLKvs7tvXX3/NiBEjuOuuu/jqq69o3bo1V199NX/7298wm41LwprLh06cRSsLyFY7sN3blm7KQQYUL6NdyhBAG3jakI65oZ7HxkbOY83JOYyNuv7AaUgWLVrEM888w/Tp0xk+fDjbtm3j7rvv5qmnnuKRRx4JW//ZZ5/liSeeCFs+b948EhISqn0c8+fPr/a2DdHOPQqggLMUMLH/wEHmzNkfeLyg0Iy/CcKPS5cDZlJL9+J+7U5OUA5xRG3BvaYHuGzdEVinldPv3+t7zkps3ryZOfmbYv6ampOm9vtYX+Q8xkZF57GkpCRm+6lSMFSdu287duxg4cKFXHPNNcyZM4dt27Zx55134nK5eOyxxwy3aS4fOtvyQfsvMPGN92TuVr5gSMFClvzYH7BQ5nI3yLFVDe08NlZyHmtOzmFs1NUHTm1p1aoVZrOZnJycoOU5OTlkZmYabvPII49w7bXXcvPNNwPQv39/iouLufXWW3nooYdQQkqzpkyZwuTJkwM/FxQU0KFDB8aOHUtKSkqVj9nlcjF//nzGjBkTqJpoCr4+thryjtC2dRoH9xynZas2TJhwYuDxqVuWQKn2OzVoyFC6bJ7DTOVZkh257FNb8QfnFOIzejJhwojANqvnZLMkZ0+l++7Tpw8TRnWO+WtqDprq72Ndk/MYG9GcR3+iJBaqXCZXVV6vlzZt2vDaa69hNpsZMmQI+/fv54UXXogYDDWXD52NBwp4ZZPWPnuOZzh3W75gOOvodfpwHvttFV7VxDnnjEeJMBldXWuo57GxkfNYc3IOY6OuP3Bqi81mY8iQISxYsIALL7wQ0D57FixYwKRJkwy3KSkpCQt4/NUKqhpelmW327Hb7WHLrVZrjX4Ha7p9Q+P0zSuUHKe9Jo9K0Ovz6pocxB/N5mPbE7RWCyC9B5ft/zMHSae/WQnaxm6N7lLFrJib1LmsD03t97G+yHmMjYrOYyzPb5WCoercfWvbti1WqzWoJK5Pnz4cOnQIp9OJzWYL26a5fOikJsYFvt+idmCbtx3dlQOk7PsB0II+VTFjtZrJL3Hx4JfrueTELM7qnRHhGetGQzuPjZWcx5qTcxgbdfWBU5smT57M9ddfz9ChQxk2bBjTpk2juLg4ML71uuuuIysri2effRaAiRMnMnXqVAYPHhwok3vkkUeYOHFixBJuUTmHSxsTlORroOAMmWfI/3hn00GG/fg4NlMh25QudL/xWw7+XRsraw65AWg1SwMFIUTtqdJfGP3dNz//3bcRI0YYbjNq1Ci2bduGVzdocuvWrbRt29YwEGpOEoPmHSrvKmfd8lVgqf+D5Pnvspm97iA3vf1rXR6iEEI0CldccQUvvvgijz76KIMGDWLNmjXMnTs3UNa9Z88eDh48GFj/4Ycf5r777uPhhx+mb9++/PGPf2TcuHH85z//qa+X0CT4u8ml+LvJhQRDZS7t8ZvMc7G5C1nj7coDyc9CUuvAOhYJhoQQdajKf2EmT57M66+/zn//+182b97MHXfcEXb3Td9g4Y477uDo0aPcfffdbN26ldmzZ/PMM89w1113xe5VNFKhk7B+49GCIWX7ApLRaqqdbu2DZHdew6/bF0KI+jRp0iR2796Nw+FgxYoVDB8+PPDYokWLePvttwM/WywWHnvsMbZt20ZpaSl79uzh1VdfJTU1te4PvAnxBzv+zzeXJ7jk0OH2EoeDC81LAXjBfQVllqSgdUJLwy3mhlEqLoRomqocDFX17luHDh347rvv+OWXXxgwYAB//vOfufvuuw3bcDc3cdbg0/+72p6t3ixMHifnWH4DyoOh0FIDIYQQoqEp85XB+ccMuXSfXaqq4nB7Ga+sJMVUQkFcO5Z5TwhMuOoXmhk6p59Wht+xpXEDpSSLFnCd3adNbF6EEKJZqVYDhUmTJkUclLpo0aKwZSNGjODnn3+uzq6aNJPJxE9/OROH28OYf/wEaHMO9VQ+41zzz3ziPqU8GHJLMCSEEKJh82eG/JOu6oMhh+9z7ArLIgA2tDkf9bgSlgkKHTPUrXUSy6ecRVqCjd6PzA3b5yMnehhx2ll0bJUU9pgQQlRGCnHrWcf0BHpkJAd+nu3VyjpGmdaSQnHgg8QlmSEhhBANXGiZnNurBj3WxXSQk5XNeFQTa9InAIRlhkKDIYC2LeKJsxo3trAr0LZFnOFjQghRGQmGGohxJ2hlhj37DYXWfbDiYbSyKnAnTTJDQgghGrIyl4fS0MyQ7rOrzOXlcvMiAH70DuSI0goID35Cy+QqY5IhRUKIGqj1eYZEdF66fBATNudwVu828PNFsGgz55pXBMYKSWZICCFEQ1XkcHPa8z8EGiYk2X1jhvSZobIyLjVrJeEfec6kpW98UWgwZJQZEkKI2iKZoQYiyW7hgkFZ2qDTEy4E4FRlHd7iY4BkhoQQQjRcS37P5WixM/Cz0Zgh9fd5tDblc0RNYYF3MA5fFkmCISFEfZJgqCFq3YudSmdsJg/Ju+cB5bN6CyGEEA2N3RJ8OZEUmGeo/LMredP7AHzmOR03lsCcRErYmCG5NBFC1B35i9NALY07FYD03bMBcPo+NIQQQoiGxhFSveBvdhCYFqLgAC0P/AjAx57TtW0ilMlVdcyQEELUhARDDdQvCacB0PLQMig5GjTPkKpKlkgIIUTDUVjmCvrZ6psoNVAmt+Y9FLys8PZmh9oOIGJmKPRnIYSoTRIMNVC5cR3Z7O2Iorphy5ygWbz1rUqFEEKI+lbkcAf9bDNrlxeqCm63G1a/C8BH7jMC6/gnaA3NBHVpZTy5qhBC1AYJhhooq1nhG8/J2g8bv8CjC4CkmYIQQoiGpLAsOBjSzwnk3PYjHNtFqZLIHN9celA+J5G/TG7WH4dx/YhO3Hxq1zo4YiGE0Egw1EDZzErgQ0PdsYhUCgOPSZttIYQQDUlomZzdogTm/1FWzwJgWfyZlGEPrOMfZ6T4gqFTe7TmiQv6RZxcVQghaoMEQw2UzaKwU21LXnIvTF43Y82/Bh7LLXKwK7e4Ho9OCCGEKBeaGTKZTCRYzbSgCPu2OQB8qYwGyttuBzJDMkRICFGPJBhqoGy+NqXbW48B4Dzl58Bjo6f+xBkvLpKASAghRINQGDJmCCDeZuFC81JMHgdk9mdFaXsA2raIA8IzQ0IIUR8kGGqg/INPt6SfDcBIZSOtORa0zoqdeXV+XEIIIUQofWYoM0ULdhKsCleaFwLgGnQteSVaKV3bFvGAPjMUfTDk71J3Zq/WAMRb5TJGCFEzlvo+AGHMnxk6Ys3iWPpg0vJWc5F5Ca95JgbWMSF304QQQtQ//5ihi0/M4oFzegMwyLyDPspevIqNHZnj8XjXkxJnoV2qFgz55xmyVKFObvFfz2L9/nzO7t2GBdmH6Z2RwG9LFsb41QghmhO5pdJA+TNDDo+X9a3OA+BS809AeVc5mYpBCCFEQ+DPDF16Ynva+DJD57m/B+BQ+3FsPqY1ReiVmYzNF/z458+ryrxCmS3iGNM3A0UxMaZvRiALJYQQ1SXBUAPlzwy53CqL7adQqtroqexngGlHYB2TRENCCCEagCJfMJQcZ9UWOIs51fEjANs7XMyWHK0jaq/MZKzm4EsPs4wZEkLUIwmGGih/MOT0eNheYGau9yQALjP/GFhHPj+EEEI0BP4yOX+nODZ+Sbxawk5vBv/d34F/L9oOQK+MZKyW4EuPqmSGhBAi1iQYaqD8d86cbi97j5bwqec0AM43L8OOEyBoIlYhhBCiPni8KsVOrRlCIBj67R0APvGcwffZhwPrjujWioSQeYQkMySEqE8SDDVQdt+ds1KXl33HSlnuPYGDpNPCVMJo5TegvN5aCCGEqC9Fuk5ySXEWOLIF9v6MB3PgRh7A5DE96d4mifQke9D2EgwJIeqTBEMNVGqCDYCNB/IpdXkwm80sTtDmHLrUVyrn78QjhBBC1JdCh1YiZ7Mo2C1mWD0LgG0tRnKYtMB6/i5y6Um2oO0lGBJC1CcJhhoo/4fFjiPaxKrdWiexPHksAKcp68jgaGDCOiGEEKIueL0qOQVlQcv8neRS4izgdsKaDwDYmHlh0HoJNq08rlVoMCRjhoQQ9UiCoQaqVWJwGUGvzGSOxXVgpbcXZpPKReYlONyeejo6IYQQzdGT32xi+DML+GFL+TigQn0nua3fQkkuJGVyKOOUoG3jfcFQesjnmyKZISFEPZJgqIFqGXLnrGeG1o7UX399qfknHK7ogiGPV2XLoUJUVRouCCGEqL63l+0C4PGvNwaW+TvJJdktgcYJDLqaeHtw0ONvnNAqOWTMkGSGhBD1SIKhBio9MTgY6pWRjM2sMNtzMiWqne7KAVodXx/Vc035fB3jpv3Ef37aUfnKQgghRCV255UEvi9yaJmhTpajsG2BtnDwHwJlcX4JNq3TXKLNHGgSBGCWKxEhRD2SP0ENVJzVrN1l8+mVmYzNolBMPN/65hzqn/tNVM/18a/7APjngt9jf6BCCCGatQJfmdxY5/eACp1PhfRuxNssQev5y+RMJhOtdB3lpExOCFGfJBhqwFr6skOJNjNZqfFYzdoHxqee0wHof2wBuEorfA59aZyUIgghhKiJTukJge/LfKXahWUuFLycWjRXe+DE6wHC5hPSZ4r0HeUsEgwJIeqRBEMNmP/DokdGMopiwuYrK/jZ24d9aivivUWQPTvi9sdLnIx8bmHgZ4mFhBBC1ERLXQm3v1SusMzNKGUDaa4ciGsBfc4DIMEeORjSP48iH05CiHokwVAD5u+40ysjGQCrr7BaReEz/0R2a96LuP17K/ZwML+8BaqUIgghhKgJr7e82qDEqZXHFZW5ucK8SFs44AqwavMJtQwZ+xqvC4b0ZeAyz5AQoj5JMNSAdW+TBMCQztqkdTbdgNPPPKdq32z/AfL3AzB3w0FW7T4WWEf/oQVSJieEEKJmPLrSa6dvrjtv0RHGKr9oC0+8LvC4flwQgE3XKUGfJZJgSAhRnyQYasDuGd2Dz+4YwSUntgcgyzd7N8AeNYNNtv6ACus+ZPWeY9z+7m9c8u9lHDheiqqqhDbSlsyQEEKImvDo5vr2T/zdP28uNpOHvBYnQGb/wONpCcGZIZPuhlyCrrmClMkJIeqTBEMNWJzVzJBOLQN3zbq1Tgp6/Hv7aO2b1e+xcHNOYPnI5xbyzwXbwp5PYiEhhBA1oa842HushLs/+I0hR7XOpge6XBa0bkUZH33JnDRQEELUJwmGGhF/2ZzfIvNIsCbC0e24dq8Ieuwf328N2766d9/+t/YA/1t7oFrbCiGEaDr0ZXIPfbGBPet+oodpH6WqjWPdzo/6efSd5qRqQQhRnyQYakTahMzane+xQd8LAOib87+w9dWQOrnqBENFDjd/+mA1f/pgNcW+ifWEEEI0T56QsahXmH8AYLb3ZCwJLaJ+Hn1mSMazCiHqkwRDjYgp5APD4fbCoKsBONO9hDgcFW6vVON/u0QXALk8oaOQhBBCNCf6YCiRUiaalwPwofuMoAYJfkbLIHjMkDRQEELUJwmGGpl/XDEw8OHicHuh0yjKkjqQbCplnL+bj09oC4XqZIa8Ev8IIYTw0QdD55l/JtHkYLu3Lb+qvQLTP+jpM0B6+m5yUiYnhKhPEgw1MhcNbs/ce7S22g6XBxSF7AxtgrtLzT8FrevSt/2hesGQvj7cE1p3J4QQolnx6j4H/CVyH3nOAExB0z/46ecT0pMyOSFEQyHBUCNk9w089bc1nWs+A4BRykbakRtYz+EKDYaqvi+3LqAKnbdICCFE8+LPDPUw7eNEZRsu1cznvknAjTJD/7xqEPFWM49P7Bu0XOYZEkI0FBIMNUJ2S3mZnKqqrDiezHJPXxSTysXmxYH1/MGSX3UyQ/rskmSGhBCiefNnhsYovwKwyDuIXLTGCUbjg4Z0asn6x8dyw6guQcslGBJCNBQSDDVC+rKDIoebEoeHT3x35rRSOe3DqszlCdquOh84TreuTE4yQ0II0ay5fZ8DA5UdAPzs7R14zKhMDsBiNJbIqm+gEMsjFEKIqpE/QY1QnNUcuKt2tNiJ0+PlW+8witU4Ois5DDVtAcIzQ6Hd6KIRlBmSYEgIIZo1/+dAf18wtN7bNfCY1Rz9Z0xQAwUZMySEqEcSDDVSaQk2APKKnThcHkqJY5FlJACX+RophGaGqlOJoA+GvFImJ4QQzZrXq9Ka47QzHcWrmtiglpe/WSNkhoxImZwQoqGQYKiRSk/SgqGjRc5ABuh7+xgAzjX/TDxlYZmh6sQyzqDMUDUPVgghRJPgUVUGKNsB2Ka2o4S4wGOR5hQyou8m55Y57IQQ9UiCoUaqZaIvGCp24vQFPVts/djtbUOSqYxzlF/CMkNub9WjGf1Eq9JNTgghmjevFwYoOwFYp3YLesyom1wk+klXHW5PBWsKIUTtkmCokfIHQ3nF5Zkhm9XMp75GCpeZfyS/1BW0TXXuvrl02SW3BENCCNGseVSVASYtM7RWN17IrJiqVO6mXze0ikEIIeqSBEONVHogM+QIlLLZzAqfe07Fq5oYad5EfMn+oG1c1cgMOWXMkBBCCEBVVTxeLwMMmidUpUQuVOiceEIIUZckGGqk0nzB0KECR2CZ3aqwn9Ys82qT251VtiBoG091MkPSTU4IIQTgVSGLXNJNhbhUM5vVjoHHLFXoJBeqY3pCLA5PCCGqRYKhRsqfGTp4vDSwzF+v/anndAAuYBEmyoMZVzWCGadbJl0VQgih3RDzZ4Wy1Q44sAUeq0577C/vGsXzlw7g5K7pMTtGIYSoKgmGGqmWiXYADuaXBZZ1SIsH4DvvUArVeDoqRxjmm3MIwO3L8pQ43Xy1Zn/YmCIj+gYKkhkSQojmy6uqhiVy1TWoQyqXD+1Q4+cRQoiakGCokUqJ0zrx5BZpZXJ2i8K9Y3oy7oQMSoljtmc4AJeafwxs42+g8NAXG7j7wzVMev+3SvcjZXJCiMbi1VdfpXPnzsTFxTF8+HBWrlwZcd0zzjgDk8kU9nXuuefW4RE3Lh6vygCTFgytDekkJ4QQjZUEQ42UzTe5XaCTnEUhNcHGf64dSq+MZD7xlcpNMK8gAS175O8G98VqrbHC4t9zK92PTLoqhGgMPvroIyZPnsxjjz3Gb7/9xsCBAxk3bhyHDx82XP/zzz/n4MGDga8NGzZgNpu57LLL6vjIG47vNh7ihrdWBm6yhfJ4PfQPZIa6BD1WjSo5IYRoECQYaqTsFnPEn+OsCqvUnuz0ZpBocjDBvAKo3jxDMumqEKIxmDp1Krfccgs33ngjffv2ZcaMGSQkJDBz5kzD9Vu2bElmZmbga/78+SQkJDTrYOjdn3ezaMsRfsg2DiDJ20GKqZQy1cpWtX3QQ3KvTAjRWFkqX0U0RP7MkJ9d93Oc1QyY+NRzOn9RPuZS80986jkdl0dFreInlsutHzMk0ZAQouFxOp2sWrWKKVOmBJYpisLo0aNZvnx5VM/x5ptvcuWVV5KYmGj4uMPhwOEoz5gUFBQA4HK5cLkqH38Zyr9NdbatLaVONwDHih2Gx+Xd+wsAG9XOuMMuH9R6eS0N8Tw2RnIeY0POY2xEcx5jeY4lGGqk7JUGQ/C551Tus3zCycpmOphy2KtmVHncT9CYIbnzJ4RogHJzc/F4PGRkZAQtz8jIIDs7u9LtV65cyYYNG3jzzTcjrvPss8/yxBNPhC2fN28eCQnVbw09f/78am8bazm52o201es3kXF8Y9jjPXb/j1RgnUHzBJfLxZw5c2r9GCNpSOexMZPzGBtyHmOjovNYUlISs/1IMNRIhQZD+kxRkl37bz1IOku8/TjNvJ5LzYv5h/vSwLihaAWNGZIGCkKIJujNN9+kf//+DBs2LOI6U6ZMYfLkyYGfCwoK6NChA2PHjiUlJaXK+3S5XMyfP58xY8ZgtVqrddyxNn3HMiguom3HrkwY3yuw3On2YrMoeGa+AhgHQ1arlQkTxtXZsfo1xPPYGMl5jA05j7ERzXn0Z+djQYKhRqqiMrnkuPL/1vm2sznNs57LzIt4zX0ubq+KyRR9fbdTuskJIRq4Vq1aYTabycnJCVqek5NDZmZmhdsWFxfz4Ycf8uSTT1a4nt1ux263hy23Wq01uuip6fax5PSl/4ud3sAxTfl8PV+s3sfCe08h88h6ANapRm21TfX6OhrSeWzM5DzGhpzH2KjoPMby/EoDhUYqPBgqb6DgzwwB/BI/EjW5He1MR3nG+iZut4eqNP2R1tpCiIbOZrMxZMgQFixYEFjm9XpZsGABI0aMqHDbTz75BIfDwR/+8IfaPswGzz/JdqGjvBb/g5V7KHN5mb1wEYq7jEI1noOW9gzv0pLRfcrLEqWbnBCisZJgqJGymSOXySXHlUfL9vgkuPRN3KrCBeZlmH97K2im8IIyFxdNX8rL3/8e9HxOt5efth6hoNQdWOaRdkFCiAZq8uTJvP766/z3v/9l8+bN3HHHHRQXF3PjjTcCcN111wU1WPB78803ufDCC0lPT6/rQ25w/FM1FJa5wx5rW7QJgA3eLpgVMx/dNoI3rh8aeFw+HoQQjZWUyTVSFrOCWTEFsjWRyuSS7RZMnYbzovcqHjC/R9KiR+ivPMpqX833Gz/tYPWe46zec5y7R/cIbPfMnM28vWxX0D69XpXght5CCNEwXHHFFRw5coRHH32UQ4cOMWjQIObOnRtoqrBnzx4UJfgm0pYtW1iyZAnz5s2rj0NucBxuDxAhGCreDMA6tQuKImkgIUTTIcFQI2YzK5R6tQ8vu9U4GPKXzP2XiZzoyWYsq/in+WXOdT9NAUms2Zdv+NyhgRBomSGpgBVCNFSTJk1i0qRJho8tWrQobFmvXr2qPN1AU7MrtxiH20uvzOTyMrkyF7/uOkrH9PIueW2Lta5867zdMBsEQ1ImJ4RorKRMrhHTB0D6srmgYMj3vUVRuN91G66UjnQwHeEl638AlW05hYF1y1yeCvcnY4aEEKLpUFWVM15cxLhpP5Ff4gqUyW0/UsylM5Zz5guLALDhIqNUK6Veq3YNKrUuf646O2whhIgpCYYaMX0ApG+goB8z5M8MWcwmCkji4NgZOFULY8yruMU8mwP5ZYF1j5U4K9yfR+ZcFUKIJkN/f2vvsfA5O4qd2g2yXqa9mFU3bnsa+9TWWKRMTgjRhEgw1IjpmybYIo0Z8meGfIFTcXp/nlWvB+Bvlg8ZaiqfkPBYccWz+UoDBSGEaDr02X7/eCEjA5XtAJS0GgCYpExOCNGkSDDUiOmbJtgjdJPzZ4asvg8vt0flI8bwlWckFpOXf9leIR1t3FBlmSGZdFUIIZoOr+4Gl8MVOfU/wLQDgOJWAwBQDK4c5F6ZEKKxkmCoEbPpSuP044f08wwl+L43m7VgyOX1YsLEFNfNbPO2I9N0jGnWV1HwVhoMub0qEg8JIUTToA+GyirIDPVXtGDo3T0tATBLGkgI0YRIMNSIBZXJmfVjhsqDIf9HltV3K8/tUTGZTJQQxx2ueyhR7Zxq3sCfzF9wrKTiMrlv1h1kyi9mlmzLi92LEEIIUS+CyuQiZIbiKaOnaR8AnxxsAxDUWntg+xYAXDCoXW0dphBC1CoJhhoxfWlcvK38+zhr+GxAFl9myO31Bmq7f1fb85DrJgDutnxO8r6fKtzfuv0FlHlM3PjfVTU9dCGEEPXMq4t//J3kQp1g2oXZpJKjpnKYNCA4M/T2jcN4+cpBPDihT60eqxBC1BYJhhoxfTCUGm+rcF2LPjOkW/6F91Ted5+JYlIZk/0wFByojUMVQgjRwOib4kSaWmGAshPQ5hfy0zdQSEu0ccGgLMObcEII0RhIMNSI6VtrpyYET4d6Zq/WxFvNTOjfFgCrLzPkNLj794T7ejZ6O5HoPg6f3AieisvlhBBCNH76MrnIwZDWSW6tt2tgmVE3OSGEaKwkGGrE9E0TUhOCM0NvXn8Sqx8dQ8tEbXlWWjwAO3KLMIUMfnVg407X3ZQqibD3Z1jwRC0fuRBCiPqm6jJDpRHGDPU3aZmh9aoEQ0KIpkmCoUasosyQopiCyhb6ZWmDXNftyw/qIOS3W81kZvr92g/LXmGM8mstHLEQQoiGQl8mV+J0hz2eQjHdlIMArPN2CSxXpJucEKIJkWCoEbNWEAyFGpCVCsD6/fm4Pcb9sVfGnwIn3wnAi9YZtDcdjs2BCiGEaHD0ZXKlzvAyuX6+8UJ7vK05RkpguWSGhBBNiQRDjZi++0+L+IqDof6+zNDuvBJKI9SGu71evm5zK4dS+tPCVMJ068vYqXjuISGEEI2TvptcicHngn+y1XW6EjmQYEgI0bRIMNSIleju5NktFXfyaZFgrTRgcnlU/vzxJi46fCtH1SQGKDt52PJuTI5VCCFEw6IvmS5xhJfJDfBNtrrO2zXsMSGEaCqqFQy9+uqrdO7cmbi4OIYPH87KlSuj2u7DDz/EZDJx4YUXVme3IkSk7j+RpMRbKnw8r8gBwEHSmezSyuWutXzP+crSqPdh1K1OCCFEwxM8ZsggM+QLhtaHZIbcHvk7L4RoOqocDH300UdMnjyZxx57jN9++42BAwcybtw4Dh+ueHzJrl27uP/++zn11FOrfbAimNGA14qkxFWcGTpwvCzw/SLvIF5xXwjAs9Y36GbaX+nzr95zjJ4Pf8vL3/9epeOC4Np1IYQQtc+rHzPku7lm8ZXApZNPe1MuXtXEel3zBNCqCIQQoqmocjA0depUbrnlFm688Ub69u3LjBkzSEhIYObMmRG38Xg8XHPNNTzxxBN07Srp9lgxupNXkcrK5ELHEv3DfSnLPH1JNDl4zTqVduRWuP3j/9ukbff91iod17LtufR77Ds+/mVvlbYTQghRfUaZIf90DP19WaEdaluKSAjaziWZISFEE1Jx3VQIp9PJqlWrmDJlSmCZoiiMHj2a5cuXR9zuySefpE2bNvzxj39k8eLFle7H4XDgcDgCPxcUFADgcrlwuao+Iah/m+ps25B1SIsn+1AhEN1rS7JXbYZwLwp3uybxtfIw3ZSDfGl/lFuck1mrdjfcn4nyD9aqnOtb31lFqcvDXz9bx0WDMqt0jI1RU/19rEtyDmMjmvMo57jpCmqg4AuG0pPsHC50MMA3v1Bo8wQApwRDQogmpErBUG5uLh6Ph4yMjKDlGRkZZGdnG26zZMkS3nzzTdasWRP1fp599lmeeCJ84s958+aRkJBgsEV05s+fX+1tG6JTE+B4a4VTMrzMmTOn0vXzjyhUNRl4hFQudTzGG7YX6aPs5SPbU0x23cGcOeElevnHzYBWYhHN8fh53NXbrrFrar+P9UHOYWxUdB5LSkrq8EhEXdI3UCj1lV37b5oNULYDxs0TIk3PIIQQjVGVgqGqKiws5Nprr+X111+nVatWUW83ZcoUJk+eHPi5oKCADh06MHbsWFJSUirY0pjL5WL+/PmMGTMGq7XiUrHG5qoqrLv22y2sOLI7bLlFMeGuYMzOflpzqfNx/mn9F2ebVzPd9k88KQ/iHXUv6Cbfm3VgJTsLjwMwYcKEqI/r4dULweOu8naNVVP+fawrcg5jI5rz6M/Mi6ZHP1bTnxlqkxIHqAysoJOcNFAQQjQlVQqGWrVqhdlsJicnJ2h5Tk4OmZnh5U3bt29n165dTJw4MbDM68vLWywWtmzZQrdu3cK2s9vt2O32sOVWq7VGFz413b6xS00MP6cAdouCu5LxR8XEc4vrPh5U3+Nmy7eYf3wG87HtcP4rYNGe16yUZ52qcp71M1Y0p/+f5v77GAtyDmOjovMo57fp0o8Z8s9b17FlAi+Na03rH/Nxqwqb1E5h2zklMySEaEKqVDNls9kYMmQICxYsCCzzer0sWLCAESNGhK3fu3dv1q9fz5o1awJf559/PmeeeSZr1qyhQ4cONX8FImopccaxr90a3VgiLwp/d1/LQ66bwGSGdR/Bf8+HYq2xgmKSifiEEKKxUIOCIe2GmFUxcUmm1h12q9qBMsJvokkDBSFEU1LlMrnJkydz/fXXM3ToUIYNG8a0adMoLi7mxhtvBOC6664jKyuLZ599lri4OPr16xe0fWpqKkDYclH7UiJ0k7NbqjaO6D3PaJ7+w0T4+AbY+zO8cTZc/XG1ZyU3SRAlhBB1Th/TlLm0H8yKAvt/A2BdSEttPwmGhBBNSZVba19xxRW8+OKLPProowwaNIg1a9Ywd+7cQFOFPXv2cPDgwZgfqKi5SPMMxUWZGQrS7Sy4eT6kdYZju+CNMfR3rKrR8QkhhCi37XAhf/t0HXuP1k4TC6P53SxmExxYDcA6NbyMHSQYEkI0LdVqoDBp0iQmTZpk+NiiRYsq3Pbtt9+uzi5FDMQqMxTQuhfcvBA+ugb2LOf+Iw9RaL6edz1jqvQ0khgSQohwl/x7OfmlLlbvPca8e0+P+fPru8n5WUwEgiGl/YkQ3nNHJl0VQjQp1bwKFo1RSnzNxgwZSkyH676CgVdhxsvfrW/xqOUd8EY/IazEQkIIES6/VJvjaWtOUa08v1EwlOrYD2XHwWxjyvUXM+uPw6pdAi2EEI2BBEPNSPs04zma4qqbGfKz2OHCf/NZ6k0A3GSZCx9cCY7Cmj2vEEKIWmNUJpdZtMn3TX8SExI4tUfrmn9GCCFEAyZ/4ZqRJHstZIb8TCa+TbuGO5x3U6Za4fd58OY4OL4nik3lrqMQQtQ1o8xQ60JfMNRucGCZZIaEEE2ZBEPNTMtEW9iyWN31U0zwrXc4lzsfhaQMOLwRXj8b9v0ak+dvbFRVZcuhQpxuGWwshGh4jPogtCrYqH3T7sTAMqtZLhWEEE2X/IVrZkb3aRO2LCaZIcrvHq5Tu8EtCyGjPxQfhrcmwLpPIm7XVO85fvzrXsZN+4nbZjXPYFAI0bCFZoYUvLTM92WGssqDIYs5+K/0tCsG1fahCSFEnZFgqJl55Ly+XDCoHYM7pgaWxS4zVP6BqaZkwU1zoec54HHA5zfD+1fiydsZtl1TrZJ7c4n2Wn/YcqSej0QIIcJ5Q8YMdTMdwOIpBWsitOoZWG5Ryj8jnjj/BC4cnFVnxyiEELVNgqFmJjnOystXDuacEzIDy+zW2Pwa6IMaj1dl6o/7+aDrc3DaX0CxwNZvcb0yjO9evQdcpfotY7J/IZoMVYXiXK3F8eZvYMV/YO2H9X1UoonxhGSGBph2aN+0HQhKecWAVZcZio9RJYEQQjQU1ZpnSDR+Nl02yGaObZkcwIYDBfxz4TYArnruYeh/GYc+nERm3krGHXkLpv8A45+HnuNisu+6sOVQId9uOMitp3UlwVb5W8dgbLIQmrICyN8HBft1/+6H/L3a9wUHwF0WvE3WEBh4Zf0cr2gyjhQ6sJkVWiRYw7rJDVC2a9/oSuQALLoxQ4o0UxBCNDESDDVT+gGxVnNsPtz0ZXLHip2B71VVxdS6F4uGvcHir97gEessMo/tgvcvh14TaKeeRy6pMTmG2jT+5Z/wqpBX5OSpC/tVur7EQgKA0uOwZCrkbNQCnoL94CiIbtukDEjJghZZkFH575wQFSlyuDnp6e8B2PXcuWFjhgYovjJmXSc5AIsuALJIMCSEaGIkGGqm9JmhWLVN1ZfJLcjOCXzv9qpYzSbMZoXZ3pNZ5BjIxrPWws/TYcscPuZ7ppvP5z+e82q0/193HaVTeiKtk+01ep5I/DdRf9wqY4BElMoK4N1LYL9BE424FtCiQ3mwk5Kl/ez/PqWdNoeXEDGyJ68k8L3Hq+LVdZOz4qavabf2Q0gwZJXMkBCiCZNgqJmy6T7cYnanT3eT8d2fy+cXcnm8WM1KoCNRMfF4Rz+JMvgPMOd+4nb+xGTrp1xi/gm2JlSrdG7lzqNc/p/lJNjMbHrynBq/lIros14VUaVOrnlzFMF7l2qBUHwanPUIpHWGFu21YMeeVN9HKJoZfVc4p9sbNGaop2kvdpMLty0FS8uuEbczN9WON0KIZksaKDRTwZmh2PwahA7G9fPPs6PfT5nbA617wXVf86B5MofUNDoph7XSuQ+ugmO7yp/Xq/LaT9tZs/d4xH2v2JEHQInTU/MXUolCh7vW9yEaOWex9ru8d4WWAbr2Szjpj9D9bO33XgIhUQ/0VQBOtzeom9wARWueUNSyf1iLT6sS+0oCIYRoKCQYaqb0ZQ+hc0hEY9m2XDbszw9aFjoY18/pm9lPf0exzOWrzzCZWGAexdmOF5nhPk/rOrdlDrw6HBb9H7jK+Oy3fTwzJ5sLX10a8XhaJpVPJusymkmwHkheqJlylsAHV8LupWBPgWu/gHaD6vuohAjy+uIdHMgvb9Lh7yRX2npg2LpBmSEJhoQQTYwEQ82UvmmCUo2yh6vfWMF5rywJWhYpGHJ5tOX6zFGZqzyDY8JEMfE8574abl8KnU/VOmktegamn4w3e26lx5NkL6/4PFzoqNJrESJmXGXw0TWw8yewJcEfPtO6wAnRAOgzQf/6YRv/XPB74OeBij8YGhC2naU2yqqFEKKBkDFDzZS+TK4mH24erxq4UxgxM+Qrk3PrMjb6YChIm95w/f9g4+fw3UNwbCdXHrufDOtA/usZC95zgua/8PMHXACH8svISo2v7kuKKD3RRl6U44UASQ3VJ48L8rbD4U1weDMUHoC+F0GP0bW3T7cDPr4Wti8EawJc8yl0GFZ7+xOiitwR/kbbcdLTtBcAV8agsMf1nxHSQEEI0dRIMNRM6Rso1KTsocjhpkW8FSCsTaufv2zN7dFnhsoDI31i6ruNh3C4vZw/8BLoMRZ+fB7P8lc507yWM81r4R/vwaCrYfAfoGWXsH0A5BSU4fZ4ueO93xjYvgWTzupR7den11IXDJW5PMRVMvlgNLHQkUIHT8/exNXDOzGsS8sYHGUzo3rh6E4t4PEHPoc3Q+5W8LqC1139Lgy4Es55FhJifK7dTvjkBvh9Hlji4eqPodOI2O5DNFux6lkQ6YbVCaZdWExejqgt8Ca3C3tcHwxJAwUhRFMjwVAzFZQZqmTMkN2i4HAbj8PRB0OVZYZcuj6uZW7jzNBts1YBMKpbOulJyTD2Kd4qORXTrzO52LyYtMIDsPhF7avLaTD4OugzMbAP0DJDC7MPM39TDvM35cQsGErUleLlFjlon5ZQ4+d8/OuNzF5/kC/XHGDXc+fW+PmaLFWFwoOBgMd8aCOnbVuBZcPt4Cox3saWBG36aF+gBUPrPoTtC2DCC9D3wthcZXpc8NlN2lg3Sxxc9QF0ObXmzyuET6zCj0h/o/v75hda5+1KR3N49bw1RjfPhBCiIZJgqJmqyodbhcFQWXlnNU+EVIi/gYLLHUWZnP95HW7Sk7Q5VgoSOvFP97X8n/tKtv7BC6tnwfYftHEZO3+CuFSGthpHX9NANqmdySkoI13XUCFW9K2yjxW7aJ9W8+fclVdc8ydpqkqOwu/zYeu3sGMRlB4LPKQAgdNvtkPrntCmry/48f3bokNwsHPi9fDVXXAkW8vi9D4Pzn0JkjOrf4weN3x+K2z+H5htcOV70O3M6j+fEGglxX/5dF3snzdCMDRA2Q5owVBXg2BIGigIIZoyCYaaqaqMGYqzmikoM24nfbiwjF6ZyUDw4Fw9fxCk/yAObqAQTp/pMfkuaJ1YcfcZj6XfxXB8D6x5X7vbn7+XE/Z9xBz7R6z3dmbLnouwtr6ywtdUHfoGEG5v5R3r9MHTo19t4MEJfcJK66TiJETuNi342fIt7PkZVF3QbDJDejdo0wdPei9W7Stl8LirsbbuCeYo/pS1Hwq3/QQ/vQhLpkL2N7BrMYx7BgZdU/X/DK8HvrxDG9+mWOHyWdC9FsckiWbjqzUH+GL1/sDPphj9oYiUGRro6yS3Tu3KpQafBxZprS2EaMIkGGqmgscMVdxUsKKxMde+uZKnL+rHNcM7Vdpa2xVxzFD4h2uxbr4g/Yevw+3VOhuldoQzHoDT/gI7FrF17nQ6HVlEf2UX/Q/9A8+305lqPYmPPWegesdjisFcSvr4J9L4KD39Gu8s303rJDt/Oju4ZM8UswKYRsrj1ubi8QdAeduCH2/TF3qNh57nQOYAsMYB4HW5ODhnDoPTe0QXCPlZ7HDWQ9D3Ai1LdHCN9u+Gz+C8aZDWKbrn8Xrh6z/B+o+1dvCXvQ29aneyX9F8HCmqnY6YRn+jkyihq+kgoGWGjMqmrZIZEkI0YRIMNVNVyQzZLRUHEg99sUELhippoOCKppucT4luYlP94ZW5PEFjd1DM0P1svuyexQf7VnOReSk3JSymvWsXF5uXcLF5Ceor78HAK6HjCMg6EezJFe47En0AFCHuq9Duo+FjW5rldUVZgTZuZ8u3WsMBXfkbihU6j4JeE7QAKNrgpKoy+8HNC2D5v2DRs1oHuOkjYPTjcNLNUFHw7PXCN/fAmve0bNUlb0Kf82rnOEWzVNnfx+oyCob6KbtQTCr71Fbk0cIw2Akqk5N0thCiiZFgqJmqypihaO8ERiqTM26tXf69ahBE6TNDQeV1EcYuuTxejpHCTM94trS5hjt65LPn+/8w0byc5GM7tQteAJOiZRvan6R9dRgG6d3DSqT0LcMDr093nJGyYBUxzCY1lwuLY7th61ytycCupcGd3uLTtM6BvcZDt7MhLqVujslsgVPu0cYOff0n2LMMvv2LliW64F/QyqDxhqrCnPvht/9qv0sXvwYnXFg3xyuaDf3fR4hdAwWj8t4BJm280Hqv1p3TanAjQMrkhBBNmQRDzVSs5hnSi5QZcvrK41wRxgwZbXfLO78y4w9DOKdfZlQZJf0YI4dbJb/lQB5038xT7j+w6qJiEvb8APt+hfw9kLNB+1r1lrZBfBpkDdUCo/YnscrTlWtmbeL+sb24+dSugefVxz+RAj+90JdlGAtV+iyNmKrCtgWw/BWtAYJeeg+trKzXBGg/rGqlbrHWqjvcMBt+fRO+fxz2/gz/HqWVYY78c/mxqSrMnaKthwku/Df0v7T+jls0WY4I3TZryuiGzIBAJ7luAJilTE4I0cxIMNRMVeXDLdrBu5U1UAjqJqf7sI+UZbn93VXseu7coLFGDpdxZsipX8ftRfWN2CkljuK+55Ew/DrtwYKDsO+X8q8Dq7UyrW3ztS9gMCa+NLXnt++6Q+IlvuxRj6DXFynw01NDZhoyyoA1yesKtwPWfQzLX4Ujm7VlJgU6jtQCoJ7jtQCkIVEUGHYL9BwH/7tHK+Nb8ARs+hLO/xdk9of5j8CKf2vrn/+KVnopRC0IywzF6O+E26Dlpz8ztFbVbvwYZoaktbYQogmr+ahy0SjpP/Aqm2fogfG9K3w83mrmb5+uY+2+fMPH/Q0U9OVuz8/dwrbDhUDlJWfOCEFUxHVcnqAPfX1miZS20Pd8GPsU3DQXHtgLt/wA45+HfpdCaicUVHore7na8gN8PQleHQYvdueesukMN23GhLeaZXLhy2LVJapBKDkKP74A/+innbcjm7W5fk6+C+5eCzfOhpF/aniBkF5qR/jDZ3DhDIhLhYNr4fUzYdZFsOwVbZ3zpsGJ19bnUYoIXn31VTp37kxcXBzDhw9n5cqVFa5//Phx7rrrLtq2bYvdbqdnz57MmTOnjo42strKDIX+3UqlkI7KEQA2+MrkjIIdqyKZISFE0yWZoWZKUUxYzSZcHjViN7knzj+BCwdnBSZVjaTU5eGjX/dGfNyogQLA/Z+s48u7RkWc+8LPGaFM7vecQv65cBt3n9096Lkdbm/QNqH7DWKxaU0Vsk6E4bcB8Nwni9ixehGDlW1c0uYgbQo2Qkke5/Md59u/46DaEtdvF+KMv4b13i4M6tjS8AIhrEzOYPdN4roibzv8PB1WvwfuUm1ZShYMvx2GXA9xLer3+KrKZIJBV0G3s7TxQZu/hh0/aI9NeBGG3li/xycMffTRR0yePJkZM2YwfPhwpk2bxrhx49iyZQtt2rQJW9/pdDJmzBjatGnDp59+SlZWFrt37yY1NbXuDz5E6Lxuseo6Gfq3doCitdTe4c2kgETAuGxa/xkhDRSEEE2NBEPNmNWs4PJ4Io4ZslmUSgOhaPizNqFBSU5BGVBxZsjt8ZJfUj7YXl8md8GrSylxejhwvJTWvglaQQuY9PtyRmi6EMlBTwvmeU9invckPP16Mun0zrBrMd+8/wqnuX+mrekobJkJW2aS5s3kl47ncvIFt0HrXkHPExoMGdXr10lrbVUFVynYEmL7nHt+1rqxZc8mEOplDtCyPydcBOaa/+7Uq+QMuGIWbPpKywoNukYCoQZs6tSp3HLLLdx4o/Z/NGPGDGbPns3MmTN54IEHwtafOXMmR48eZdmyZVit2u9q586d6/KQA7YdLiTRbqFti3gAHKFjI2P0ZyL0b9AA3/xC630lcopJu1EWKqibXCWVBEII0dhIMNSM2SwKJU5PxLIHq8FM5NURKJMLqVfv0FK7OK8oGLrk38uCyu/0maESX8e5A8dLSdUFbQ63N2hfzooyQwYKSsuDL7dX1S7qu53F0xaVycXXc4ayhie6ZpO6dwFdlUN03fcmvPomZPSH/pdAv0u0cqtQRi+zNq8rcrdpndE2fAq5W7UMTcuukNZF+7dll/KfkzOjG5jgcUP2/7TgYP+q8uU9xsHISdD51KbXIa/vBdqXaLCcTierVq1iypQpgWWKojB69GiWL19uuM3XX3/N/7d333FW1Of+wD8zp24vLOxSlo70IovgiqARFMVrrPcSrolKLNFANCExhhRsiXhNYkwxmqtRk5tE/MWaRIKs6IKFoiC9SF9AdmnL9j11fn+cnTnfaafsHtj2eb9evGDnzMyZM5w9M895nu/zLS0txfz58/HWW2+hZ8+e+O///m888MADcDjs51ZLtZP1Psx8cjUA4ODjVwMwZ4ZSxfgZrGaGtoQjwZDTpkrAxdbaRNSFMRjqxtRgxy4z5ErRN4BaZsgQ9PTMimRzYgVDxnFI6k1CgzAP0fCiLF3A4wvqM0NqAwZfMIQfv7ENlw7vhavH9bZ9zrrm6L7FYwsrCvxwYUX4Alw/5Rv43t6PMFPegOtda3GpYwtQtTXy592HgOIpuDE4Dn/DRJxEpEzM2FABOAtlcmcOA9tfB7a+ClRu0T/WXBNpGPHFZ+btXOktQVLLHzFgyikGAo3AZ3+JlMOdqYhs4/AA4+cApQtMWTGic+nkyZMIhUIoLCzULS8sLMSuXbsst9m/fz/ee+893HzzzVi2bBn27t2Lb37zmwgEAnjwwQdN6/t8Pvh80clQa2trAQCBQACBQMC0fjzqNnsqa03LmvxB2/XbwhfQ71cNhjarwZBDsnweSfjsUsLBlBxLqqjH0pGOqTPieUwNnsfUSOQ8pvIcMxjqxtJckW8/7TJA4nJZ0jcAGNorE4MKMlC2oyru82hjhgzfdqpBUiKd2VRqZmjb0WiQlO11aSV3kXWsxwwtXX8Yf99wBH/fcARXj7va9jnEYEjsZCcmmMIK0IA0vBW+GGXKJdjxvcmRcqptrwEHPwQOr8NCrMN9HgkfhcdgWXgKspomAYHRAKLfOqekTK7+OLD9zchzH14bXS45gCFfijSGGDoDaDgJnN4PVB+I/H265e+aw5Fg5/j2yB8j2RXJjgVaJo1N7xGZmPSCO4BM81gMos4gHA6jV69e+N///V84HA6UlJTg6NGj+PnPf24ZDC1ZsgQPP/ywafmKFSuQnt76EtRPPv0E6qVYbd5QddIBMW2shEIpaeywuUqC+vnTC9UokqoRUiRsVwa2PE/Q8nl2HYtu997KlcjsgBWwZWVl7X0IXQLPY2rwPKZGrPPY2GieyL61GAx1Y/fOGIb1B05hdJ9sPHPzRCz+x3bMGNELSz+JNEMQgyGnLOsCjNw0F56aMwGjH3wn7vOoAYVxwr8mfwjhsGI5/44dNRja/kWtbpmxFK7RFy2nU4Ouk/U+JKKuOfptQ0g4ZrE1thjASQCQnh8ZTzJpHlD7BbD9DexY8QJGYS+mO7ZiumMrcOR54LH5cPYYgknBXMgf7kJJsweHpVwcUQosJ3q11VQN7PxnJAA6sBpQ1OOUgIEXA2NuAEZeC2T0iG6T2QsoHGXeV9AfCYjEAEkNmKoPAiF/ZJLUHkOB0vnA+LmAKy2x4yQ6BwoKCuBwOFBVpf9ypqqqCkVFRZbb9O7dGy6XS1cSN3LkSFRWVsLv98PtduvWX7RoERYuXKj9XFtbi+LiYlxxxRXIzk5+ouBAIICysjJMvuACYHskW3vVVVdBkiQ8ve9joKFeW1d2ODB79qykn8Ooev1hYH+k3b2aFdqj9EMTvAAAr8eN2bO/ZN5uXQVeOxjJsM264vKUjCVNFfU8Xn755drYL0oez2Nq8DymRiLnUc3OpwKDoW7sppJ+uKmkHwDgqrG9ceWYIvxj8xdCMGRopyqM6XU7ZS2zZHTVmCL8e1ul9nO0gUIkgLh8VCHKdlShKRBKKisEAM0t+9ollJb4gmFTc4Z6oYxODZTkBGvdxcxQ0GZuIXHOIVN77Ow+QOl83FE+Aq7ag7hGXoOp8naMdR1GZrgO0snP0RcAVq3H9wB8zwPUKmmQXhgLFI0Beo0CCsdEAhexE5uvHtj970gAtPfdSICi6lsSyQCNvi7y/MlwuoEeQyJ/jMKhSHDXfAboNToyHw9RB+N2u1FSUoKVK1fiuuuuAxDJ/KxcuRILFiyw3Gbq1Kn429/+hnA4DLnlff3555+jd+/epkAIADweDzwej2m5y+Vq002Pyxm9DMsOJ5wOGT6LcY6pubGKflZNkj8HEB0vBETmE7J6HodwjF6PGy5Xx7t1aOv/A0XwPKYGz2NqxDqPqTy/He8TjdqNJEm6zIQ+M6S/4Xc7ZciyBK9LNk0QWDqkhz4Y0uYZivyd5Y287Zr8oaTn61EzQ7sq63TLjB3jdKVuQXMw9PwH+zHngmJkefW/TOGwgnq/zZghMTBK4LgVAIeUIvwudD1+F7oeM4f0xPM3FCP4xRbsXv0aRuaHcXj3BvT2H0K21AQcWR/5I8opBgpHR8rU9rwbbV0NRIKTsTcCo2+IjO05G2QHkFsMoPjs7J8oRRYuXIhbb70VkyZNwuTJk/HUU0+hoaFB6y53yy23oG/fvliyZAkA4J577sHvfvc73HffffjWt76FPXv24LHHHsO99957To9b/DIlpChwQt8oJrJOap5L7J8wXY6MKfwwPEZbZjd+VFzMBgpE1NUwGCIdp10wZGim4G55LN3tRHPAr3vM69RnjLTMUDByJc5uCUCaA8kHQ75gZMLTz6uEYCgY1o3tAYB6XzRrogZj4tCon769Ezu+qMWTcybotqvzBXVle2JmSFxuKpOzYGqtDQnI7g0lrQB7dzfjvNmz8eM/b8SaPZUYJFXijRtzkHlmF1C1A6jaDtQeiZSv1QhzOOUPjnSrG3Mj0GukzTMTdT9z5szBiRMnsHjxYlRWVmLChAlYvny51lShoqJCywABQHFxMd555x185zvfwbhx49C3b1/cd999eOCBB87pcYufH+rnofELplRRy357ohqj5EMIKxI+DI/VHrfLnotjGznpKhF1NQyGSEe8GOrL5PTlUW5n5GerUjmvW79Ma6DQciHObqk3b/SH4k64atQcCOHw6UbdzYLPIjMklsmpz28sZ7Nq/iCOFwKAUMi6TE4cP5RoDwTFoiQwrCgIwok9Sj80nDcDmdne6INN1cDxnZHAqKkaGHY50HtC12tdTZQiCxYssC2LKy8vNy0rLS3F2rVrzSufS8Kvs/p56AsaMkMpnnR1urwVALBVGYTTiI53Mn7+qXSZIQZDRNTFMBgiHTEDFKtM7vaLI2VZxnIOAPA69YFTwDDPULZaJmeTGdr16JUYuXi5ZWOF5kAYpxr0jRB8wbCpgUK9rkwusiPjt57BsIJ1+0+hIMuDIT0zAejL64BoAAfoJywUny7RWwOruE/MaJkmh03LAwZcFPlDRF2SLjOkTQOg/yxIWZlcy/4vcWwGAKwOj9M9XttsbultfH7GQkTU1TAYIh0xAyQGQ+K3gWt/cCmKcjMAAKca9CVyAOA1ZIuqG1r6xbdEEGqZnF0w5HU54HU60GQRaPmCIdQ26S/YzYGQqYFCnWUDBf2+mgIhzPnfyLfC6mSHxmBIP2ZIWJ5A4wfjvEJWW4j7TzZLRkRdS0hRku6wmez+ZYRxcUtmaFVoXJwtIsTMlKlhDBFRJ8fWUKTjsCmTEzNGPTLMnZZExmBozf5T+L81B7WARW2g4LfoAhfdh/VbMxBSUNtSyqFO2uoLhrWsirqdOCmr36KBgh1jeUrQMOmq9u9Y3eRaGG9orMrkghbzIcXyxw8P4IdvbLXcFxF1PrqxiGEFJyymAEhV+BEKKxgr7Ue+VI9aJQ2blKEJbcf4h4i6MgZDpJNoN7lYrAKZx5bt0gKLbGGOCnFsj8jjtG7bHQiGtVKOnpmRYEjMDKnd4fQTpyY+uauxVM1uzJAYGCV6oxC2CobCMcrkLDz6rx3427oKrD9wOrEnJaIOTfxcCYYVXafMVAuGFa2LXE3RVAQTLA5hNoiIujIGQ6QjZoDcTjEYsn6rXDnaPKGhMTMEAGP6ZqPRH8m6ZHqiF2BjWZrK5bS++AZCYdQ26TNDTYGQNvYmq2Xf6nOp2wDRFttW1AyNMTsTDCtQFPVPdHmirbV1P1tsEhSCrXiZITEbZXfeiKhzMbbv//wsBkPhsIJLHJFgqLrPtIS34zghIurKGAyRjlhKJmaDvjwhMpFnYZr+jv7JOePxyl0XYvbYaFBk1WHuk4PVOFEXKf9wOaITtjbYZIaCIetgwx8Ka4GAGgyJQYZagqfbRm3tHSOAUSdz9Ruet9EfxOW/Wo17l27SLQ+3prW2RTQkNmgwtgc3H2M0wLPaFxF1PsZW/laZoWQyM3XNAdsyWqe/BudLewAA9f2mJ7zPRCesJiLqjBgMkY5uniEhM3TX9MH4/dwJuHe0fkxNutuJKYN7aPMOAfrM0DXj+5iew+WQkNbSfttYJieOJ7ISCIVNY4b025tnJFYDnFiZF7UrnjF79PG+U9h7vB7/3PyFbrmum1yCNwpWsZj4rXCs46uqbcYvV3xuuR0RdV4hXZfKsG4OtWQdPNmAsQ+tMH15oxpQ8wkckoJTaYMg5Q5IeL9uJ28ViKjr4icc6YhjhsQAx+WQcfmoXsg0xxoAANlmu5w0c6ZGzAzVG8q9pg/rCSBWMKRomaGCTHMwJJbgRbeJXybn0zJDiU12mFhmxtBNzrKBgjBmKMZz3/nnT/HHDw9oPzf4zZ32khUOK/i/NQex/YuaNu+LiFrH2LL/WE1zq/f1pzUHAcD05Y1qcE1L98zcC5EuzAf33cvPw3mFmXj8hrGW280cWYhJA/JwR8uUCkREXQlba5OOXQOFuNsJ2RFxeJFVyZxTyAyJLbDvvmQI7rlkCAD7wMAfjI4ZyvY64XHKWiDjcki6C7xKm+coVpmcmhlKNBhKZMyQYRWrbI74fLGCtS1H9AGLXXlhMt747Ch+8tZ2ANHW4kR0boUN2eHTDa3vJmfXeAYAoCgYWrceAHC4x0UY44mu279HOlZ85xLbTd1OGa/ew/nOiKhrYmaIdNQyOUlKbqZxsfGCuF2vLK9pXavMUO8cL35w1QjkpEdST3bBkFgml53m0pXkeZ0OLcgS+RPI+qjBkLquVVAlCiUwZsjYvc4qGNOXySVe+mbXhS8Z25gRImp34q/9yXqfVk7raUVpmljOZpoQ+8Qu5AaOo1lxoTJ3ItLc0e9COSaIiLozBkOko5a7JZMVAvQXU1mS8PgNY3HX9MG4eFiBaV2nHM0MVTf6TdsD1p3XAH0DhayWzJDK43JYlsmpQVAwZjCkdpOLPLFVRkukn2fIeh1jJsgq2AkkOc+QKhXBEHswELU/RficOF4byQrlpLn0wVCCsYq42tL1Ffpy470rAQDrwiMBVxrS43zGERF1FwyGSCcv3Q2HLKGXRXOCWMRskEOW8JXJ/fHD2SMtMywZHieGF2YBAD6rqAagzyzFIrbWzvYaMkMuGeluqzFDiu5vK+pkq+rNg1WGSZTInEXGUjqrYEwMmGJlrozzPKWiTE5Uvvt4UsEYEaWG+FlyvC4yXqgg0637TE00byN+SfLQP3fgTx8fjD64910AwOrwON0XUoBFFomIqBthMEQ6+RluvHLXhXhp3uSkthMzO+L4IWOG5V/fuhhelwOTBuYBADa3jIWJVZJ3z6VDcF1La+9AMNpAIRIMCZkhp4wMj1WZXAjNgVDMYMOnZYbClsdtFNaVtvhx7dMfmYIdY1mcVZlcIMFucsbgzNh4oq1ue/ET/O69vSndJxHFJ34hUtWSGeqR6WlV6VpdSwmx6r1dxyP/8DcChz4GAJSHx8MhS7rMky+BCZ+JiLoqBkNkMmlgPob2ykxqGzGYETvLeYWb+PwMN8b0zQEATB6Ur98+xoX/gStH4J5LhwKIzLXT1PItZqbXqRsw7HU5kGFRJvfO9iqMefAdbDxUbfscxgYK8TJDxqzP5sNnsPnIGf06irFMznzDEUywgYIxw5aaMjn98b3yyeE275OIkiP+GlbVRjNDcitmOjV+LgwrbPkcP/QREPLhtLMX9il94JQl3ZQADIaIqDtjMEQpYZfZETMs4iq9c9LQI8Ntu/0fvlaCLK8TL9w2CUCkUxygz4h4XbIuM+R1OWwbHwTDSsyWtcbW2vEyQ1ad4eJ1jzNOJBsOK7oMU6wyPmP5XyqCIaNY3faI6OwQy+SqWiam7pHh0X1eJjqXWZ0hY1yU09LApmW80La0CwBIpkDLF2SZHBF1XwyGKCXsSjrERgzGC3p2WnTSImMwNGt0EbY8eAUuG1Go2494w+52yKYxQ1YNFBKRbDe5Y7XmwEp8eYqimCZZDYZjl9EFwvbfznoNwVm8MUM1jQHc8PuP8OeWeUesGEMfYybryRW7ccsL6zmWiOgsEj8GNh8+AwDokemOmS23U2sIhrRf6ZbxQtu8JQDMYxDVBjJERN0RgyFKiUSazxmTR1neaOBivNkH9MGTsc2sU5bgdMjIEDImXqfDsoFCIpItk3t7yzHTsi1HanDNbz/Emn2nbOYUMo4h0t+A2E00C5iDs7o4wdDvy/diY8UZLG6ZR8hKvEzWb97bi9Wfn8D76rgDIko5qznLBhVk6D7/Eo2LjGOGFEUBqg8Bp/YAkgNbPecDAByy/vN08kB92TIRUXfCYIhSwnhxtWLMHonBUI6QJbJibPWtBkfiGCGPy7qBQiKag/rW2lbBWTwP/3MHth6twdzn1lp2m1PHB7278zh+s82BQ6eaDI/bl6kZA8l4maFa4aZo7/F6LN9WaVpHgblszwqr54jOHuNnRWG2B1eP7d2qfRkbq4QVAPsiJXIonox6KQNA9MurNYsuw19un2I5BQIRUXfBYIhSIpGSDuMaWZ5oAJQbLxgyZIY8LcGKGPx4ndYNFBKhdpNLdMxQPFYVb2rnuHv+tgn76iR879Wthsf1GwVCYZyq97X8W3/DFK+bnJjlueH3H+Huv2zAv7Z8EXOboE1nO7eTEzISnS3GRibXTugLp0PWZYMS/Q1Uxwxdcl5PAC2fAy3jhTBkhvaFi/rlVe+cNAZCRNTtMRiilEikTM44ZkjMDGXHzQzpt/VaZoYcurK5ZDQHkxszFI+xBA4wzzN04FSD4XH9TdH1v/8IJT99F4dPN5pK2GK1CQcA8WF1HMHS9fpucaYyOWFBoz86oNrt6HyTMzb5Q3jhwwOoONXY3odCFJPxV9n4WQck1kAhEAprnTbVTLsUCgD7V0VWGDpD+xwxjhkiIurOWnfnSGSQSBtYYyVdljcaAMUtk5OtM0NiwwSvS0Z6K8vkVu6sQsXpRpxsycSktTKoUlllhsKKvhTNmO0JhRUEQ2H88cMDmDq0ANuO1gIA3tleaWpiEK/zm7EZAgDsOFar+9nUQEHYZ5MQDLViHHe7e2d7JR751w5sOXIGT33l/PY+HCKTny3bhb+tcyAvc59uuVoSnOzvnZgtzk6LfH4V1W0B/HVAeg+g9wQEw2sA2De8ISLqjhgMUUok8k2j8QKcKWSGctNjB0OyLMEpS1oQoI0ZchvmGRKCmL65aTh6Rj8uBwCGF2ZheFEW/rE5Wjb2eVU9Pq+q135ua5mc1ZghIHbHuEAojJc+Pogl/96lW+52yqbgR1EiwZNdS3OrYOl0gx81jQHk2JxrfWYoemPVGbvJqWOmTjX42/lIiKwFwwr8YUkr0VW5Wz7bpISL4yLU7LbLIWnZ3P7VayMPDrkMkGWo378wM0REFMUyOUqJRL5pNK6TnUQDBUDfRMGygYJT1gUHhdkey/08cdM4XDAwL+Zzpbna9qthVSYHxG6SEAwpWLPvlGm5xylr5S0v3nZB3OcA7JshqGU0gLlMTvxZLJOz6ozX0annWcxwEXUk6ueh8csGt0XNcSKhS3Q8kKSVLQ86E8kEYcgMAECo5TPDYVGKR0TUXTEYopTomWUdeACRDA0AzBzZS7c8mW5ygL6W3uNUGyjYt+fOFyZ1FTkdUtwyuNa26FbZxSmxgqFAOIzqRnMmwynL2g2TRwjSYu3LLoBJdHJFMRiKNRmsqrrB36GCJrVMsJHBEHVQ6hc3xvF/xs6ZiYqOB5IhSxJ6oAa9G3dHHhxyGQAhYGKZHBGRhmVylBL/Ma4P1uw7hUkW81W8ds9FeH/3cVx/fl/dcnHMULwyOSBaPgJEgwJdMGToOJeTZh0MuR2yrrzOSrx5huJpTZlcMKSgujFgWu4LhrWbGLF8L9a4Ibvn9+nmMrLfvkEok4uVgQKAfSfqMeOXq3Dh4Hwsvas05rrninpumgMMhqhjUpPYxt9jt7OVwZASzQxJkoRpcku3yqKxUDJ74YjQiIVlckREUcwMUUo4ZAmP3zgON5X0Mz1WlOPF3Mn9TZmb5DND5jK5TI9+zJBoyiDriQRdDhnpFi24xS9L2zxmyCabEgwptjciQZvM0A/f2IrK2mYA0YwYELt8za5MThyfYBMvAdCXl8XKQAHAaxuOAADW7j8dc71zST03amYoHFbw6oYj2H+iPtZmmne2V+Khf2w3dQAkShU1M2T8PbRqoJBIIkcMdBwyMN2xJfLA0Jl46t09mPbE+9hzvF733ERExGCI2pGY1YnXWhswBkP2ZXJvzZ+KH1890jIwAyJlcmLr7H55afjL7VMwsEeGtuysZYZCYV0HPP1jCs5YZIZEbqcU/UY5xo26XdZILJOLFQzpy+RiBwQdpzguKhoMRTJcr244gu/9fTMu++WqhLb/xv9twEsfH8TrG4+etWOk7s2uVE0tBxYfjfW7qlK/tJBlCTIUTJdbgqEhM/DrlXv0z81giIhIw2CIOoSkxwypZXJufQMFABhfnIs7pg22bfftdsi6YOjXXzkfFw8rQEFmtKzOmGVKll3Wxh8K6yaKTWQbkVOW4WwJCmOVyVm11gaAZiEzZLcOoO8mF6+Nd1ttOXIGP/3XDq0DXCqo51JtGPHpodZlrb7/2hY8+q8dKTsuIpVdQOKxKJNL5DdQzAwVNn6OAqkWPjkNKJ6S8HMTEXVHDIao3Qztlan9Wyz/suMW1lHXF7MszgQHHjsdsq5Bgnrz0SMj2gSirWVydoGGVXcz9QviRDqfOR2SVmbX1gYKsYKcRl2Z3NktFfvy7z7C8x8ewBPLd8VfOUHq6w+ElDa3Bv/jhwcw/Yn3sW6/udMfUWvZfVkTLZOLPq4kkBoSxwwNPhNpqb0/swRwmsdOOo2TvhERdWP8RKR2k+11Yf0PZ2Dz4isSWt+t6yYXeeuKk6wm2s3M5ZB0DRTUAcsFWW7dsrYMMrYLVHzBkOmxQQWR8jx1XFAsTjl6XPe/uhm7K+u0x6pqm7WxQvbBUDQwiBUkNPqimaGfvLUdP3/HPlAR79MSuWmzs6cqsfE8iRADvaZAqM2TTFacbsTc59a29bCINPZlcubLclgB3t1RhU8P2mc4tbbZsoQB1ZGW2ruzzFkhwDwBNhFRd8aPRGpXvbK9tpOAGunGDLWUySXaUMC4H3FMkHr/LmaG3A65TaUkdpmhH7y2FVV1Pt2yQS1jlY4nEgw5JC0Dtu7AaVzz2w8BAB/tPYkpj63Eo2/viPn8YmYo1vkytqR++v19cY8tsv/WZ2GcKZz7RHz9Tf5QQgPQ4++z7fsgUtl9vmiZIWFZTVMAd/z5U9z07Brb/alfsmRLjSiqi4wX2p0x2XJdZoaIiKL4iUidhlUDBVF6gk0PXIYyOTVDIo4ZcjmlNmWG7AINtZuTaGBLZqghgTI5l6wP0tQ5Sn785jYAwIsfHWxZbt9NTiwhM1IzO40xWlIfOtWAi//nPbz00YHINsKIBrFbXbIcLTdob285hsk/ezfmt+DxiNm3Rn9IV3JE1BHYxSPxWmvbZV/VMrlJ4a1wKCHsDxfhpKu35bouTrpKRKRhMESdhkucZ0j49+L/GIUbzu+L6ef1NG0zqnc2AOC8wkxcNaYIX7mguGWGdgmXnNcTI4qyMKIoCwCQn8LMUDJNB9RgKBEOhwSXxXEZW3L7DMGMWhb45qajGPvQO3h3R5VWViNSAySxTE71/z45jOZACD99eyeOVDfhoX9GslBi4NGc4KSuVtTXNf9vG3G8zodv/N+GhLetbvDj9+V7caymCYA+M9ToD+Js3Pq9vL4Cd/zpE85lRK1iVybnjjP20W4SZPVLjknBzwAAq8LjbbOZrZ3LiIioK+Kkq9RpWI0ZAoCvXzzIdpvnb52Elz4+iFtKB6BfXrrusZfmXQBFiQ5kFjvauZxywg0ZrPgSCAry0l0ozk9H//z0uOuqnLIEh+Fb3VBYQU1TtBNbTWMAfkO5WpbXhQZ/SJsL6I4/f4ppwwosj9vtlE1lckCks9pnh6tNN//iz20JDIxlcskElN9/bQvKdlThzc+OYsV3LtFNFNscSE2ZnNGi1yOTWv51XQVuj/EeTFRzIAS3Q7YdWE9di22ZnLNluc3bQP0dNYr8viiYFNwIAFgdHodcmyxSvICLiKg74ScidRpimVyira/75Kbhh7NHmgIhINKtSbzxzE6LfjfgdrStgUJ9szmzYvTP+aX4x4KLk7oxcTlkuAz1NQdPNeiaGDxZthv7Tzbo1hEnuFVZNXlQg6gzTdZtrl9ef9g0Hkls193UpmBI/7qsBpLbWbmzCgDweUsTBrE3RKM/BCmJ3FCyTSCssmjJqmkMYNzDK/Dfz7NJQ3dhFwzF+zz4cM9JzP/rRi0LqgqHFQyWjqEwfBwhyYW14ZG2YweT+d0iIurqmBmiTsNtUyaXKgPyo+VqrjYGQ3/fcCTuOurNfzL1+7Jkvok6YyiR+9OaQ6btLIMhizI5XzAMRVHweVWd6TGV8f5KnxlqQwMFw+tK5rw4HbIuGyaWADYm2UAh2UYJxkxda7y/+zj8wbCWuaOuz67DoVUDBdE9f41kfrwuB375X+O15cGwgkvkzQCAqryJaGryskyOiCgBDIao0xjaU5iXqI3zAFnJSXdh2b3T4HRExhS15Sa3bEdV3HXUm/9kyvEkSTKtn0jTgiyvuWOfVRmaPxjGsZpmnGm0nwDV+G1zU4rK5IxBXiLfXiuKgseW7TSVBYqZoSZ/KKkxQ8nOS9SWoFmVaCdE6jpsM0NO8zxDVup9+t/RUFjBJXKki9wXBVOBL6C12jdiZoiIKIrBEHUaFwzK1/59tmreR/XJ1v59ttvPasFQkjfTxvUTaWedmWCZnC8Yxr4Tsef7OW5oDZ7smKG9x+uwseIMbprYT1emaCz/SyQztO2LWvzv6v2m5WJmqCmQXDe5WGOVynZUoaYpgAnFudoyRwreJ6E2zM9EnZNdZijRz7ZBBZm6n5VAE6bIOwEAxwouAuCPUSbHcWlERKpWXcWffvppDBw4EF6vF1OmTMH69ett133uuecwbdo05OXlIS8vDzNnzoy5PpEd8Qb0dIPffsUUaUs3uUSoGZ5k59cxrp9Is4Zsi2DIKgPiD4ax81htzH3tP6Efj5RsZmjmk6vx/Ve34K3NR3XfXBszcYl8e201RunVDUd0AY2xTC7emKCQTbcuALjzz5/ie3/fjJlPrtKWpSIz1JbJaqlzsnt7q10z472rvC5Z977JPfEp0iQ/Tjt6oDZ7GIBoFld8i7odMlvNExEJkg6GXnnlFSxcuBAPPvggNm7ciPHjx2PWrFk4fvy45frl5eWYO3cu3n//faxZswbFxcW44oorcPTo0TYfPHUvXpcD04YVwO2QLTuhpVoqbnJjcWmZoeR+DVuTGbIqk7MqzfIFQ1rmJ5FvqBVFQZO/dWOGNh46o82TBMDUMjxWkHisphllRyXL5/ve3zfjw70ntZ+b/PoGB3atibXHLcZSxRIvaK5pCsQN3sW4lCVz3YNdRjHRrM1T7+7B9b//WPtCoWdVZALmbd5JkFv2rb6vxCwUs0JERHpJB0NPPvkk7rzzTsybNw+jRo3Cs88+i/T0dLzwwguW6//1r3/FN7/5TUyYMAEjRozA888/j3A4jJUrV7b54Kn7efG2C7D+RzNQnEQ76tayuhlPZXyklogle3NivPlOaMyQx6qBgvmmuzkQ1jrh5aabAygjXzCsC8aSGTMUVhTdtsl0k7v9zxvwrwoHHnh9m+Xj4pinRn9IdzMYL9iwKh+MJdb/n6IoGP/wCkx8tAyNfvuuc2KZXLJjlqhzsnvbJFMCvOnwGRw9E+kqV3g8EgxtT79A+5xStMyQEAyxeQIRkU5SY4b8fj82bNiARYsWactkWcbMmTOxZs2ahPbR2NiIQCCA/Px823V8Ph98vui4hNraSNlOIBBAIGA/sNuOuk1rtqWojnIeM1zSOTkGj8VNidi17Jc3jcV3X93a6v1rryGsDyC8Ltk2wxIIBEyTNTb645+LdLf5tVjddJ9paEZdc2R/uWku0/ggo/omn+4mv8GX+O9oMBRGQ5OwfyUMny+aQXHK9v/Pe45HSvVO1scvl6xvDuiyaU0+H5ySfaDX5EuyBFMJ2x5nUDjHB0/UYVivTMv1AoHoOWzy+eE4R8M5E/mdbu/f967KLqOolrAlWskmyxJQcwQ59fsQUiTsTi/B1JaNtTI5GUDLxwznGCIi0kvqinvy5EmEQiEUFhbqlhcWFmLXrl0J7eOBBx5Anz59MHPmTNt1lixZgocffti0fMWKFUhPb31GoKysrNXbUlR3OY8NNTKMyVNJCUGt5t+6ZROA1ne1U89jjR8QfxUdwnMYLVu2DKdP6Y9r05ZtcY9j/+7tpnXqGxpNz/PRJxtx8IQEQEaoqc72OFRvLy9DXYNDW2/T1u0oOL0NB+sAlwwcbZAwoYcCt+6pI6+1oqICy8sOaj/v3X8Ab729T/u5pvoUli1bZvPMiX907dl/EF4HoJ6zf79ThkxDLOQLAYEwkOkCTjQlt/8tm7fg0M4teO2gjDmDQxgS7cGBSAVhZF+rV6/GHpuPr23HJKj/P/9evgIZ8ZNyKRXrd7qxsfEcHkn3YddAIVkSAOyNVFpsVobA58rR9q0mOfVlcgyGiIhE57Sb3OOPP46lS5eivLwcXq/Xdr1FixZh4cKF2s+1tbXaWKPs7Gzb7ewEAgGUlZXh8ssvh8t1ju8yupDudh6X1WzCrhr9WLg0txu+lglJJ5eU4KXPN7V6/+p5PN3gx+IN5dryrHQvGmqtMzKzZ8/GP6o/w84zJ7RlQ4YNBw7thdsZzVoVZLqR5XHiwKnIjexFF0zEX/du1raRJcDl9gB+fRZk4LCR2NZcCdTWYnC/QuzbaT0WUDV1+qUIbfkYQOR5/1nhwF3XlGLhM2u1crRtvhy8+o0p2jb3rVkBACguLsbUqQOBzz4CAPTvPwDTLx0MrI80Jyjs2ROzZ5dYPq+6j0T0KOyDnlke4Fhk/qVLL5uBXlke3Trn//Q91PuCWPuDS1Hd4Ac2fZzw/kePHYcfvrkdAPBKRQY+/P4l2mP1viCw/j0AwLRp03BeYZblPr748CBw8HPt+Hoaju9sSeR3Ws3MU2rFG2uW6ETBYUUB9kWCoVWh8XDIEtThSF+cacLh0426bDLnGCIi0ksqGCooKIDD4UBVlX4OlaqqKhQVFcXc9he/+AUef/xxvPvuuxg3blzMdT0eDzwe882Ay+Vq0014W7eniO5yHrPS3KZl4rgWr8U4nGSo59FreKu7ndE0ypIbxmLR61v12zj0GZ6AErnRyfa6cLI+EkR5nA5dnU2GV/9aZEmyHDPU4A+joaUhQo/M+Dfk/rBkauBw/2vbdONyNh+pQVCRkeY2ZK8kCSEhw6VIEgKK8DOklLzPmoMKFPHGUnaY9lvvi5Sp7aisR1F2WlL7l4SB8CEFun1LAaFbntNp+3rEU6gIx1fTGMALHx3Adef3xaCCDMttUyHW73R3+F1vD3KKBiCGggFgXzkAYHV4HAbIkpYJ2nu8HtOeeN/UTY6IiKKS+lR0u90oKSnRNT9QmyGUlpbabvfEE0/g0UcfxfLlyzFp0qTWHy3ROZRhvHmHfrB8quYhMg7AVxC9gZ47uT/65upvzu1aa2enRYMzj0vWzTHicepfiyRZNwqoaQpoDRRyEmigUNNkHk+yq7LOtGzV5ydMyxRF3xY8FAb+teWY9nOqGgk0BYK64CxW6+x1B05j9m8+SGr/4r775EYy3tUNfvxyxW7sPR6dsylWkzoxoPy/NYdw2S/LUXGqET95axt+vXIPZv86uWOiji9et8pEq+gcxzYCvho0O7OxWRkChyybSvDE7z1cTnaTIyISJf3V9sKFC3Hrrbdi0qRJmDx5Mp566ik0NDRg3rx5AIBbbrkFffv2xZIlSwAA//M//4PFixfjb3/7GwYOHIjKykoAQGZmJjIzrQcTE3UEGRaZHzEQSWZ+oNF9srH9C+tyIzGocjtk002zsZzGeBO1YnskU5uTFg1ePE6HboZ6j8sw9skmM1TbHERDS5YkL92cGcv2OlHbHB3sf6YxsWYDasZKnBclrOiDgE8PnsbL6yu0n1MWDPlDutcaq3X2H1aZJ3CNRz1fANA7JxIMff+1LSjbUYXfvrdXeywY43nFoPDZVfsAAD99ewc2HzkDwHo+JercUjVmKO3Q+wCAw3lTEK6X4ZBj75tjhoiI9JIOhubMmYMTJ05g8eLFqKysxIQJE7B8+XKtqUJFRYU2xwEAPPPMM/D7/bjpppt0+3nwwQfx0EMPte3oic4iq2BIvJFI5Kbi/lnDcX5xLgJhBbe+YD3ZsJgZcjkkU+tnY/BjbEF94GSks1q2MJeQ2ykj3BRdJ8Otfy2yZH1zXt3o18rk8iwyQ31y01ArZH5OJxgMqXMRifMKKVC0MU4AsEfIogCR1t8n6nzwuGRUnGrEiKIs02tPRKM/pJvc1ZgRC7dxXh/1/ANAest5Xm2RCYsV3FnNFRUIhcG5WLuuVMUk6RXlAIBDuaXA4cj8RbH2zWCIiEivVYMeFixYgAULFlg+Vl5ervv54MGDrXkKonaXblUmJwT6VmUuQ3pmYHhRFpZtjWRAs9NcuGhoAT7YY745VkmGOUCMGZt4mSFVti4zpL/h6ZGpz/KEw9bzDFXWNGv/zrEYM2XcjzqfT5rLgfP75+Ljfacsj62xJRgSJzxVFOBIdTRiS3c7tPUA4FS9Hxf87F3t53suHYIHrhwBIBLMWcUw91w6BM+U79MtawoYMkOGoCTZSVaN9p2IBnFqcGcV3PiD9pGN1fxMrQn8qPNIRWYoD7XwnNgCAHhkV2TcrlOWdJ8pRiySIyLS49WWyEa8MjmXQ8b737sUd00frC3L9LowsX+e9rMalPTLS6wlvNsh60rJAItgyKY8L9srjBly6scMGUve/DZZhy9aJnB0yhIyLV5/foa+qYJaJped5sTNUwZYHhcANLbMoyNmgjYfOYMfvhFtDiEGQgC0ySRVYpBj9+32f5b0Mz+3P4SQEPCU7z6Op979XMsIxZuENR4xM+SPkf2JXSZnfszlkMDEUNcVr5tcIqbJ2yBDwc5wMSoCudp+YwVaKarOIyLqMhgMEdkwlpYB+m/rXQ4Zgwoy8F+TirVlHqesy8qo/x5UkIHnb4nfPMTtlBEyRCnGGxu7xg3ZhjFDYjCU6I2XOh4o0+u0DLryDaVz1UJmKMtrn2hu1jJD0Zv+/Sca7Fa3lCUEZ3YBodU4p2Z/CGJl3C9WfI6n3t2Dd3dWtRyTdcgxpm82CrPjd9QTJ371WwQ1qphlchaT7DplmWVySXr66acxcOBAeL1eTJkyBevXW5emAsBLL70ESZJ0f2JN+ZBqxsmTJw/Kx7sLo23ZY2V3VNMdkazQ6nC0Q6tDlmKWySXaspuIqLtgMERkI91jLpNzWzRQGNAjHROKc9E3Nw23XTQQHld0OzEwmjlKP1mxFbdDNo8ZMtz42wU24pihSGYo7tPZyvQ4TV3uAOC8Iv08OWpmyBsnGFKzPrGChXj65Ueza1ad8ADr/7PGQAhBi0CkuuXYrR4DIsFIsh0DYwU8dkEXoG+goD2/QwKYG0rYK6+8goULF+LBBx/Exo0bMX78eMyaNQvHj9vPlZWdnY1jx45pfw4dOnTOjtf4ezx3cjGG9oo2FYofsiiYLkeCoVXh8drSuGVyjIWIiHQYDBHZsCoTE6njh1wOGW/On4qPfnAZZo/trQuAkp3g0O2UTQP6H/ryaEgSsPDy8wDYZ0XEbnKyLJmyCskcS6bHaRkIXDaiF+6dMQxpLQGfmhmKBEP2rbgbA+YGCskqasnSKIpiWVaW6XFazqESCiuWY3LUMVFWY6eASJlaMh0DgdZnhpotMkMui8zQ8bpmNPqDpnUJePLJJ3HnnXdi3rx5GDVqFJ599lmkp6fjhRdesN1GkiQUFRVpf9RGQOeCMRiyKm2TEIYbAaSjGdmoRw/UoBCn0U86gUvkLeglnUGj4sGn4eHR/bBMjogoKW2bNZKoC7NqoKA2DADsgxKvLjNk3kcsLoe5gcLE/nnY9eiV2r7sylzEeYYURTGNPcr0OHE6mFj3t0yP0zID5ZRlLLz8PJxu8OEvayu07Eqay6Ebs2TUlERmqHRwD6zZb27EoL4aq0CoKNuLN+dPhSRJcDtkU9BV12wfQNgFKU5ZTnpcR6yAxy6bBdhnhsQtjtc2Y/JjK5HlcWLrw7OSOq6uzu/3Y8OGDVi0aJG2TJZlzJw5E2vWrLHdrr6+HgMGDEA4HMbEiRPx2GOPYfTo0Zbr+nw++Hw+7efa2kir/EAggEDAPN9WPL02PoX33P8PLoTglELIWwYoy8NAOACEgvhnKACHN/7vy5rwKPghTPSrKFDC9q3YFUVp1fF2VOpr6UqvqT3wPKYGz2NqJHIeU3mOGQwR2bDKDFUnEAy1JTPkcki6sT7RfUaDKsWmdMqYmTHuJ9PjxOkG+2Ao0+NEvS86ZsiqSYHayc7bcjynWsbLpLljZ4aSCYbEoE6kdWqzyKJcNbYIRS1z/HiciQVD6jp2DRScDsk0riMeq0DN+HyJbudy6JtgfHKwGgBQ52NmyOjkyZMIhUKmzE5hYSF27dpluc3w4cPxwgsvYNy4caipqcEvfvELXHTRRdi+fTv69TM34liyZAkefvhh0/IVK1YgPT2xBimiwYd2YKxcGV1g+NW0+xoloDgQhAMBOFCPNLwU0gfG+/ftgXTCfg8nT57EsmXLkj7ejq6srKy9D6FL4HlMDZ7H1Ih1HhsbG1P2PAyGiGykWzRQONUQ/WbYZTOeRAxcjC2u43E5ZNx+8WA8u2ofZo8tslzHblC9V3guBebW0/HK/rK90WAoJ81lnRlqCQCHtIxtqGlSy+RkeF0ynLL1ZK6NgRCOVDfiq8+vi3kMgDmoU6nBULNFFkUM3NxOGfDpH6+3CCACLfuzG8vjlKVzmBkyb+ewKHWk1CktLUVpaan280UXXYSRI0fiD3/4Ax599FHT+osWLcLChQu1n2tra1FcXIwrrrgC2dnZST///p198J8vX6QFNvdfOQoXnVcEyE7A4ca8v2zG9somBOFEAJEAKAgH4o0mGjl8OEoG5OLpHZ9aPt6zoCdmzy5J+ng7qkAggLKyMlx++eVwuey/kKHYeB5Tg+cxNRI5j2p2PhUYDBHZyLAYjC/enDpsy+TaNmbou1ech0vO64nz++darmMsf1OJjRus1rtsRC/sOGb/4ZGd5sIXLfMMRcYfmZ9HDTqmDinQLfe6HJAkCVlepy57pmryBzH3ubUJZTWMjRi8LhnNgbAWMFhlhsRmD1bnvK7ZfExqpsau5bXTISc/ZihmAwXrx8p3H8dew4SzQGQuJbv/a6PDpxvx6oYjuO2igcjLMHfU6+oKCgrgcDhQVVWlW15VVYWiIusvFYxcLhfOP/987N271/Jxj8cDj8fcXdDlcrXqpkfqOQyfKNHmDr6C0XD1jh5rjeMoqlGT9H5dLgfcMY5HlqUueZPW2v8H0uN5TA2ex9SIdR5TeX7ZQIHIRpor9ngfu0HK+sxQcmOGPE4ZLoeM0iE9dGOPRHb3x8YslLHM7VszhuIn/zHK9rnFbnQ5aS7LbnRqpqR/j3T0y0vTlqvnyi6r0+AL4fDpJsvH+ufrS4yM+1CPK6nMkIFVEKbuzy5j42pFmVwgqFiO/wHMwVAwFMaafadw24ufWK4fDNsVRJrd9OzH+PXKPbj/1S3JHG6X4Xa7UVJSgpUrV2rLwuEwVq5cqcv+xBIKhbB161b07t37bB2mTiINFFrDKUtIwRRGRETdBoMhIhuSJOEblwzGl8f3wVcv7A8A+MoFxRhRlIVx/XKQYdFgAWhbZshuMlGR3Q2yLhhSgD98rQQ9Mtz49VcmtDzuwO0XD8IwoX2vSByrk5Pmsmwg4RTuskb3iZYGqYGbOm6nT45+vhbjBKoi4/MYGzGoXfLUrIt1Zsg8t5P4b6sAUg1OYpW2JVomp67mD4XR4LMLhvQH8fvyfZj73FrbfYbCiu4/W7xXNmaMqmojdYEf7zuZ0PF2RQsXLsRzzz2HP/3pT9i5cyfuueceNDQ0YN68eQCAW265Rddg4ZFHHsGKFSuwf/9+bNy4EV/96ldx6NAh3HHHHefkeI3vrVRMwhrZjxyntTYjJSIiEcvkiGJYdNVIAJEswuyxvVEyIA9OWYYE+5sKt8XNeKJizdWjsmqwYHxeBQomDczHpz+eaTpOuwBNnLQ1J82FfnnpeODKEfif5dEB6OK+8oVyLDUztOSGsdh8+AymDO6B215Yj8tG9MIfVu+P+XqMGbBsQ2ZIPSexM0PWZXI5aS4cr/OZ1gei43TsWmuHworlt/XDemVij6GsLd0dGW/lD4bRYFMKaAy6ninfZ7meypgZEo8kEFLgdpqPze690R3MmTMHJ06cwOLFi1FZWYkJEyZg+fLlWlOFiooKyMI4v+rqatx5552orKxEXl4eSkpK8PHHH2PUKPvsaSoZ31tygsHQ3Mn98fL6CtvHHVLswIqhEBGRHjNDRAlwO2VcNKQAHqcDDlmKeeMi3ogkkukBgJ/8xygM6ZmB710xPO66dve7VvMCWQVsatMDI2OZHADcc+kQ9M1Ns1xfFwy1ZHeG9MzEDRP7oW9uGsoWXoI7pg22PliBKTNk6CanBmlq+Vm8zJA411DfPOtjB+KXyVl1mZtQnItl900zLVdfvz8UtmzWEHke/XE3Wcx9ZFzfbsyQXQe8tky02xUsWLAAhw4dgs/nw7p16zBlyhTtsfLycrz00kvaz7/61a+0dSsrK/H222/j/PPPP2fHai6T0z9u9V3LtRP64FuXDY29X4ccs0yOiSEiIj0GQ0QpJgYVYslcLLdfPAgrv3spemV7465rd4Oc6RXnGbLfPi89GsSIgYgxMxTv+cT92GXA0mxKCXXrGDJDxjFDOVow1JIZsggi7MYMDci3b3kciNNAwSpj5HJIlgGueh5jZYb8MbrJJfr8qoDNMSfacIHan7E3h3F8mlXM4pCs338iZ7xJVxM9QCKiboLBEFGKZXiceGv+VPxzwcWmBgo/uGoEAOCSovjz7dixukd+a/5UZHqcWjvuO6YNst3+vhnDcNWYIqy+/0v4zszzAABfHt9HN1YnJz1+lxarzJBRvCYUVttmeJy6b68TaaDg1o0Ziu7P2JxB1JrMkPpt/lcuKNYtF9uwb6yottyfMTNkdOHgfNPz24U2dsfc3TNDnYkxu5zIWB5JknQloVYcUpxgiKkhIiIdjhkiOgvGF+daLv/G9MG47Lwe2L5uVav3bbxF7pPj1Z7vd3Mn4sx1AV2gYjRzVCFmjoqMo7hj2iBcPKwAw3pl4vWNR7V1ctPit2e2GjNk5JAleJxyzMlIjWVyaS4HXHJ04lS1bM4XjJSNWZXJOW3GDPXvkWH7vP44DRSsgiH1JvNn14+FxynjT2sOmV7DY8usJ/mM1agBMJ/DYEjRZfjEw7ELrLrzmKHOxhmngcKwwixsPlJjWCd+6W2kjNf+8UEF9r8TRETdETNDROeQJEkYVJDRpta3xnt0p3BzJMtSzEDI6nhG9s42zamjK5Oz2VZ8Hrs24IA52DE/rv9OJs3l0B2LWHYYCClxW2uLN5kJZYZs0imxytQcsoRiYd/xXiMABOKkbYznIRgO6wJfsZzP7tgYC3UexuyNMcb5ydWjtC6W0XWkuHNfOR32maEbzu+L71x+XvIHS0TUhTEYIupkjDe8t140MOX7TWSskzhmKNb6YmBlxRhIed2yLqARt/eHwlpmyCVFD1gMhhyJBkOh+N3kjMR7TPGGM5GugQEhO2Y1F5GxXDAYUgzZIMXy39Q5GTNBxvK1nHQXfnrdWOQJJauyJMEVK+3Tsl+7YOin149BpocFIUREIgZDRJ3MNy8dggy3A3Mn98erd5diXoqCoQE9ooFDIuMKemRGg6FYGYkhPa3nNVIZy8PSXA5dqZvYUMEfDGuZIXFYkziOQrzJzPI6bduVR8cMJV4mJ8H6eaw6+RmJQVd1g7mjnzG7FDTMMyRmhuwaKFDnYcoM2fzOib+LshS7k6W6H7tVUjWxKxFRV8KviIg6meL8dGx+8ApdeVwqTBqYj59eNwaDe+rHFNgFOmIQ0+i3bxM9rDALK3cdt33cGAR4XQ5dcJHudsDlkBAIKfAFQ1pmKNMJ1Pgj69hlhhyyhEyPE3XN5g5viTRQMI7rEOmCIUPp0kPXjMJD/9yhfz4h6DpZb577yBgURhooiGVyiu4x6tzMrbWt32viaolMzBorMxTr/UxE1F0xM0TUCaU6EFJ99cIBuGhIQULrit9Yj++Xa7vesF6xM0NeIRhyyJHWwWJw4XHJWrc4XWbIaV0m5zQEQ3bjedSGBnZZFqvyOcnmxtQ4qP3y0UXm5xPK5I7XNZseN5bJBUJhXSAqBkDxmjFQx2eMS+ySi8bMUDxOh2QbNCUSTBERdTfMDBFRq33yo5k43eBH/x72Y3MGFtg/BgDpQkZEDXpchlbZbqeMBn8I/mB0zFCGUCbndooBkJAlkiRk2IyR0MYM2WaGwgDsGyOIZU3iTabXJVt+Ay8GV9uP1poet84MRQUsxgz5g2Esen2r7TFSxyVJEmQoCLeUXtoFKuJSu+9ARvfJxvYvIu8pWZJsJ1ZlW20iIjNmhogoJvvZboCeWR4ML8qKuf3I3tkAgB4Zbozuk216XMzceFoaMTgNwYU6d5AvGNaaD2QIMY5YVifeMMqGzJA61gqIlsnZZVkKs70xXrl+nhhxzFKG22l5Yys+z9ajNabHrcYMiZOohnTd5CL/fnl9BV7beMT2GBVFwf4T9aiqbUaYpXUdjl1DDpGcQGboxon9tH87ZZljg4iIksDMEBGdVeluJz77yeWQJQkhRcH7u45jQ0U1/rauAoC+PEzNDOkzLdGGCr5gGM1qZkj49BJv843NDDKEltX/vm86Pq+qw8vrK+Bvya5Yjb+55Lye+Nn1Y3Df0k265ZIuG2T9nGluh2VmSAyGthmCIYcs4WS9X7cs0lpb/NmcGfriTJPpeURNgRAu+2VkTqsdj8wyte+m9iVLgJrwS2TMkF3zBLFDnEO2L5MjIiIzXhmJ6KzLE+YkurGkHw5XN2o/i+VhambIIyzLSXNpwZBfzAy5xOAgGmgYbwTTxRtFh6TbF2AeG3R+/1z86euTAehLlIw/i+V4zoQyQ5HnqWkK4Isa/ZghpyyZ5k8yTroaCJqbKcSazBYAGnyRfUoS4HXGnwuJzi0xbLctkxMDcJuAKd0T/b+VJdiWyRERkRnL5IjonBMDIDFboZbD3XLhAEwbVoBfzRmPgkyPljH644f7sWxrJQDAK9zbi9kdY1YmQ8g8OWUxGIoECsYyOTGTZMwZ6RooSGKZnDEzZP5oVQO2umZzW22XQ8bXpw7C5EH5mDOp2PSaAP3cROox++M0Umj0R7ropbkccVsy07kn/pe4bCZTlSwyQxcP1Tc5Ed+zIUVhmRwRURIYDBFRTLHmEGotcZLSNHf032rQc2NJP/zf7VNw/fmRsRBqxujdndEW3U4JmD2mECN7Z2PigDxtufGmXyzDk6VoMLTvRAMOnGwwNVAwdnWzI5bJid/qZ3gclt/yq2V5apmfyOWQUJjtxf/7RilumhR5zcaMlZgFUgMlf5zMkNrynOVxHZP41hPn0xLpxxVF/v7z1yfj7kuGaMvF8WahsGKbQSIiIjNeIYnonBPL4DxOc5mckdXgf5cM/HrOeDidTl0pkTEzJGahnLKkBVwA8KVflJv2K2aSYpXJid++u2QJ+RlunG7w48rRRdbd5FqyOM2BaOmaGmg6LeZJChpafuszQ0rL34llhjI8LJHriPzh6Psk06broWxRJifLEnKFWYfFAD4YZmaIiCgZDIaI6JzzuqzH24gZI9HmI+bua+oujO2CjVkZrxAMiWOG7IhjjMxlctbttJ0OGW/fezE2HKrGVWN6Q5YlXbADRAMXNcMjTgbrsAjmjFkfX8DcTc4qMxQKK9qxqWOGjG27qeOxGzOk6yYnWwf9YllmOKxAYs0HEVHC+JFJRDGdjYbMaS599yuV22aQ//jiXNMymySSqURIDH4ckj4zZCU9wcBBHwxJ6J2Thv8Y10dbbswOqdkcX0tmKMsmE6De2FbV+nTLrcrkrBooiAGSWiZnN9cSdXz6ph3Wwbg43sghSyyTIyJKAoMhIoqpX15ayvf5pRE9MaZvNr5yQbHuxs0uUHnyv8Zj0VUjMFCY3NUlW4dpDsNAdDHb5JAluJLIDMXuJmdfmmd8HADqfUEoiqJ1jbMbI+K0GUifaJmcPhiKZJ6McxhR52HXtMNpyEx+67KhuGxEL0wb1pNlckRESeDXhUQU02++cj4e+sd23DV9cMr26XE68K9vTQMAnGmMzq9j11FrSM9MDLkkE+9sr8TBU5G23HaZIWNA5Y0xZsiKGDgk2k3OqntcZFk0MKlpCmDKYytxY0mkQUKm1/rj165cSgxy1PFHauZH5AuFAEQCrQatgQKDoc5KDGx07z+xtbss4btXDLdcj4iIYmMwREQxFeen44+3XXDW9i/blP5YyRSyKXbB0JwLivHnNYdw2YheAMyZoXhjhjJiBg7W4zesgjir13K8zodnyvcBsA9QXBaBFaAviQu0lMnVt4w5EolBU5PaQIHd5Dq0WMGqPgCyzgy5DAE+M0NERInjFZKI2pXdfD1WMj1ilsd6nSyvC6vuv1RrdiB2q5MkSde8wUqsNtS2N6YWx21VOicSj0sRclDGMj+VbsxQS2ao3hc7GFIbKKSzm1yHFisYkm2adsiGMWuieF8qEBFRFMcMEVG7ijf2RiQGKu4Yn15i1zdj8ONxOvDL/xwf4zla0UAhzpihr104wPS4XVDmsjkH4pghdQ6iWosJXH2WY4b4vVdHFjsAFwIgm4yPMZvIWIiIKHEMhoioXYk3eHbNA1RiiVucajdNfobbtOzGkn44v3+u5frpMTqv6RooxDluMUCafl5PvHp3qe5xr03XOrtv9cXW2oGQAkVRLDND/7t6P1ZsrwQgTrrKzFBHFrNMTvi3+LuiCH3bje8/Y7t5IiKyx68LiahdOZMYMyRmTeJUu2kmFOfi9osHmbriKTY9w1s3fsN8MGK5m9MhYdLAfOSlu1DdGMnm2GWGrPYF6DM+Db4gVu48bvka3vjsKN747Ch+NWc8/rquAgDHDHV0sVqfi28HsRpT/K+P9yUCERHZ4xWSiNqVHCeoEIljcxK9/5MkCT/5j1Gm5YpNNCQGQ9k2Hd8A/bf0Vg0UnIZuXwAwsCAD1RVnAABemzmVEmmt/bv399oel+o7r2zW/p3GzFCHluiYIV2ZnPD2tWu6QURE8fETlIg6jHhjhuI1WEiG3WSyYhblkWvHYHy/HO3nr104UPt33MyQ8Lj6zX9RtldbJpbJiXGZXXbMOAlrMjLYQKFDS4sx0a/d3FZi0w2Zg4SIiFqNmSEi6jCsurKJ7OYhao2vTx2Eb7+yybRc/Ja+OD8dby24GMFQGJW1zeiXF530VbwxteoAJwZ22S0twfOE8Uv2ZXKpv7FlA4WOqcCr4GSzhBsm9rVdx66Bgl2ZJxERJYdXSCLqMM5lZujaCX0wrDATmR4nXtt4FL9ZuQeAdQMFp0PWBUKAPhiyKlMSb2Kz0yL7zE8Xg6HkGigkYtKAPHx6qNq03JNotwk6p747NoTBEy7C5MEFtuuIlXGyLjNERESpwCskEXUY8QaClwzIS9lzSZKE0X1yMKBHBi4d3lNbHqtkSRSvm5wvEB3jY5UZsgtQku0EJmay/n53KQoyzd3zmoVjoY4j3QlM7J8b8/9cN88QM0NERCnHzBARdRjxMkNThxbg2a+WYGC+F7s/WZWy5+2bG+00l2hmRkwGWZXvNfijba/VLFB+hktb5kkw6Iolw+3QZQskSWopifNry8b3y8El5/Vq83NR+xDfjvpucoyGiIhSgcEQEXUYjgS6Yl05pgiBQAC7U/i8hdle/P3uUi2Dk4h4DRQafeZsTK5NmVxrb2szPE5dy21Anyn64ewRuGv6kFbunToCCfpgl4iIUotlckTUYaSyQUKyLhiYj+FFWQmvL5YsWWWT6v3mCVF1Y4ZSMI4n0+OE8akzhTFPuWnmkjnqXDwusZ189D/7mvF9UJDpxjXj+8Tc/qIhPeB1yfju5eedtWMkIurMmBkiog6jLc0DzjVdZsgiiLMa05GfEb+BgujmKf3x1qYvUO8zB1YAkO5xoKZJMiwTgqH0xDNd1DGJwa3D0KFw7aIZcX9nRvXOxp+/Pjlup0Yiou6Kn45E1GEkU6bW3nSttRMsXxIbKMRSnB8Zw7TgsqExg6Z0t9M0x0ymMKeQWJZHnVOWMPGv8f/a6ZDjls5JUvyW9URE3RkzQ0TU7n44ewTW7T8dt+SnI9E3LkhsmwxhPE+j377DW9l3LkG9L4iCTA/8Qfv1HJJkKpMT5xRiZqjzyxK+IGhN4pTjjIiIYmMwRETt7q7pQzrdQH8xGxTrhlN8SFxvVO9s2228LoeWETI2SBApUExZKbE1OIOhzk/MDCWagRQxFiIiio3BEBFRK4hlcrHuNzPd+o/ZtYtm4FSDD/17pKMg04OT9T5cPNR+0k1/yD4YAsyBWFgYrMQGCp2fOGbIWCaXCJnREBFRTAyGiIhaQY7TTU41uq8+A1SU40VRjhcA8MY3L8LbW4/hv6f0t90+3uSaI3tn4eiZJu3ngBA8uVPQsY7alziOrjUNRhgKERHFxislEVEruJ0yrhxdhIuHFqB/frrp8de/eRG+PL4PfjVngu0+ivPTcfclQ5JqHHH/rOHavxUFWHLDOMyZVIx/LJgKAAiEOBlnV6JroMAyOSKilGNmiIiolZ79WontYxP752Fi/7yUP+es0UX4+TvRKWd7ZnnwPzeN0372xxhjRJ1PWxsosEyOiCg2ZoaIiDoRj1D65rJomXzthEhHvhFJTCBLHVem13qeoUSNjNGog4iImBkiIuo0fnz1SBTnp+PHV4/E78v3YfE1o0zrXD6qEG/On4rBPTPa4Qgp1VpbJvf2vRdj8+EaXDWm6GwcFhFRl8FgiIiok7hj2mDt79svHmTZ0luSJEwozj3HR0ZnixgMJVPxNrpPDkb3yTkLR0RE1LWwTI6IqBMwdobjZJrdg9hcoznA8WBERKnGYIiIqBPwWIwPoq5PHCPW5A+145EQEXVNvLoSEXVgcyYVAwC+c/l57Xwk1B7EDOBwNsUgIko5jhkiIurAHrthLO6YNghDe2W296FQO9n84BVo8AXRM8vT3odCRNTlMBgiIurAHLKEYYXMCHRnOWku5KQlPjEvEREljmVyRERERETULTEYIiIiIiKibonBEBERdQlPP/00Bg4cCK/XiylTpmD9+vUJbbd06VJIkoTrrrvu7B4gERF1OAyGiIio03vllVewcOFCPPjgg9i4cSPGjx+PWbNm4fjx4zG3O3jwIL73ve9h2rRp5+hIiYioI2EwREREnd6TTz6JO++8E/PmzcOoUaPw7LPPIj09HS+88ILtNqFQCDfffDMefvhhDB48+BweLRERdRTsJkdERJ2a3+/Hhg0bsGjRIm2ZLMuYOXMm1qxZY7vdI488gl69euH222/HBx98EPM5fD4ffD6f9nNtbS0AIBAIIBAIJH3M6jat2ZaieB5Tg+cxNXgeUyOR85jKc8xgiIiIOrWTJ08iFAqhsLBQt7ywsBC7du2y3ObDDz/EH//4R2zatCmh51iyZAkefvhh0/IVK1YgPT096WNWlZWVtXpbiuJ5TA2ex9TgeUyNWOexsbExZc/DYIiIiLqVuro6fO1rX8Nzzz2HgoKChLZZtGgRFi5cqP1cW1uL4uJiXHHFFcjOzk76GAKBAMrKynD55ZfD5eIcQq3F85gaPI+pwfOYGomcRzU7nwoMhoiIqFMrKCiAw+FAVVWVbnlVVRWKiopM6+/btw8HDx7ENddcoy0Lh8MAAKfTid27d2PIkCG6bTweDzwej2lfLperTTc9bd2eIngeU4PnMTV4HlMj1nlM5fllAwUiIurU3G43SkpKsHLlSm1ZOBzGypUrUVpaalp/xIgR2Lp1KzZt2qT9+fKXv4wvfelL2LRpE4qLi8/l4RMRUTtiZoiIiDq9hQsX4tZbb8WkSZMwefJkPPXUU2hoaMC8efMAALfccgv69u2LJUuWwOv1YsyYMbrtc3NzAcC0nIiIujYGQ0RE1OnNmTMHJ06cwOLFi1FZWYkJEyZg+fLlWlOFiooKyDKLIYiISI/BEBERdQkLFizAggULLB8rLy+Pue1LL72U+gMiIqIOj1+TERERERFRt9QpMkOKogBofRu9QCCAxsZG1NbWsrtHG/A8pgbPY9vxHKZGIudR/dxVP4cpgteljoHnMTV4HlOD5zE1zvW1qVMEQ3V1dQDADj9ERO2krq4OOTk57X0YHQavS0RE7S8V1yZJ6QRf94XDYXzxxRfIysqCJElJb69Ojnf48OFWTY5HETyPqcHz2HY8h6mRyHlUFAV1dXXo06cPGxAIeF3qGHgeU4PnMTV4HlPjXF+bOkVmSJZl9OvXr837yc7O5pszBXgeU4Pnse14DlMj3nlkRsiM16WOhecxNXgeU4PnMTXO1bWJX/MREREREVG3xGCIiIiIiIi6pW4RDHk8Hjz44IPweDztfSidGs9javA8th3PYWrwPLYfnvvU4HlMDZ7H1OB5TI1zfR47RQMFIiIiIiKiVOsWmSEiIiIiIiIjBkNERERERNQtMRgiIiIiIqJuicEQERERERF1S10+GHr66acxcOBAeL1eTJkyBevXr2/vQ2pXq1evxjXXXIM+ffpAkiS8+eabuscVRcHixYvRu3dvpKWlYebMmdizZ49undOnT+Pmm29GdnY2cnNzcfvtt6O+vl63zpYtWzBt2jR4vV4UFxfjiSeeONsv7ZxZsmQJLrjgAmRlZaFXr1647rrrsHv3bt06zc3NmD9/Pnr06IHMzEzceOONqKqq0q1TUVGBq6++Gunp6ejVqxfuv/9+BINB3Trl5eWYOHEiPB4Phg4dipdeeulsv7xz5plnnsG4ceO0SdVKS0vx73//W3uc57B1Hn/8cUiShG9/+9vaMp7LjofXpihel1KD16bU4LUp9Tr8dUnpwpYuXaq43W7lhRdeULZv367ceeedSm5urlJVVdXeh9Zuli1bpvzoRz9SXn/9dQWA8sYbb+gef/zxx5WcnBzlzTffVDZv3qx8+ctfVgYNGqQ0NTVp61x55ZXK+PHjlbVr1yoffPCBMnToUGXu3Lna4zU1NUphYaFy8803K9u2bVNefvllJS0tTfnDH/5wrl7mWTVr1izlxRdfVLZt26Zs2rRJmT17ttK/f3+lvr5eW+fuu+9WiouLlZUrVyqffvqpcuGFFyoXXXSR9ngwGFTGjBmjzJw5U/nss8+UZcuWKQUFBcqiRYu0dfbv36+kp6crCxcuVHbs2KH89re/VRwOh7J8+fJz+nrPln/84x/K22+/rXz++efK7t27lR/+8IeKy+VStm3bpigKz2FrrF+/Xhk4cKAybtw45b777tOW81x2LLw26fG6lBq8NqUGr02p1RmuS106GJo8ebIyf/587edQKKT06dNHWbJkSTseVcdhvOiEw2GlqKhI+fnPf64tO3PmjOLxeJSXX35ZURRF2bFjhwJA+eSTT7R1/v3vfyuSJClHjx5VFEVRfv/73yt5eXmKz+fT1nnggQeU4cOHn+VX1D6OHz+uAFBWrVqlKErknLlcLuXvf/+7ts7OnTsVAMqaNWsURYlc/GVZViorK7V1nnnmGSU7O1s7b9///veV0aNH655rzpw5yqxZs872S2o3eXl5yvPPP89z2Ap1dXXKsGHDlLKyMuWSSy7RLjo8lx0Pr032eF1KHV6bUofXptbpLNelLlsm5/f7sWHDBsycOVNbJssyZs6ciTVr1rTjkXVcBw4cQGVlpe6c5eTkYMqUKdo5W7NmDXJzczFp0iRtnZkzZ0KWZaxbt05bZ/r06XC73do6s2bNwu7du1FdXX2OXs25U1NTAwDIz88HAGzYsAGBQEB3HkeMGIH+/fvrzuPYsWNRWFiorTNr1izU1tZi+/bt2jriPtR1uuL7NxQKYenSpWhoaEBpaSnPYSvMnz8fV199ten18lx2LLw2JYfXpdbjtanteG1qm85yXXImtXYncvLkSYRCId1JBIDCwkLs2rWrnY6qY6usrAQAy3OmPlZZWYlevXrpHnc6ncjPz9etM2jQINM+1Mfy8vLOyvG3h3A4jG9/+9uYOnUqxowZAyDyGt1uN3Jzc3XrGs+j1XlWH4u1Tm1tLZqampCWlnY2XtI5tXXrVpSWlqK5uRmZmZl44403MGrUKGzatInnMAlLly7Fxo0b8cknn5ge4/uxY+G1KTm8LrUOr01tw2tT23Wm61KXDYaIzoX58+dj27Zt+PDDD9v7UDql4cOHY9OmTaipqcGrr76KW2+9FatWrWrvw+pUDh8+jPvuuw9lZWXwer3tfThE1AHw2tQ2vDa1TWe7LnXZMrmCggI4HA5TZ4qqqioUFRW101F1bOp5iXXOioqKcPz4cd3jwWAQp0+f1q1jtQ/xObqCBQsW4F//+hfef/999OvXT1teVFQEv9+PM2fO6NY3nsd458hunezs7C7xrREAuN1uDB06FCUlJViyZAnGjx+PX//61zyHSdiwYQOOHz+OiRMnwul0wul0YtWqVfjNb34Dp9OJwsJCnssOhNem5PC6lDxem9qO16a26WzXpS4bDLndbpSUlGDlypXasnA4jJUrV6K0tLQdj6zjGjRoEIqKinTnrLa2FuvWrdPOWWlpKc6cOYMNGzZo67z33nsIh8OYMmWKts7q1asRCAS0dcrKyjB8+PAuUYqgKAoWLFiAN954A++9956p9KKkpAQul0t3Hnfv3o2Kigrdedy6davuAl5WVobs7GyMGjVKW0fch7pOV37/hsNh+Hw+nsMkzJgxA1u3bsWmTZu0P5MmTcLNN9+s/ZvnsuPgtSk5vC4ljtems4fXpuR0uutS8r0hOo+lS5cqHo9Heemll5QdO3Yod911l5Kbm6vrTNHd1NXVKZ999pny2WefKQCUJ598Uvnss8+UQ4cOKYoSaWGam5urvPXWW8qWLVuUa6+91rKF6fnnn6+sW7dO+fDDD5Vhw4bpWpieOXNGKSwsVL72ta8p27ZtU5YuXaqkp6d3mRam99xzj5KTk6OUl5crx44d0/40NjZq69x9991K//79lffee0/59NNPldLSUqW0tFR7XG0ZecUVVyibNm1Sli9frvTs2dOyZeT999+v7Ny5U3n66ae7VOvNH/zgB8qqVauUAwcOKFu2bFF+8IMfKJIkKStWrFAUheewLcSuPYrCc9nR8Nqkx+tSavDalBq8Np0dHfm61KWDIUVRlN/+9rdK//79FbfbrUyePFlZu3Ztex9Su3r//fcVAKY/t956q6IokTamP/nJT5TCwkLF4/EoM2bMUHbv3q3bx6lTp5S5c+cqmZmZSnZ2tjJv3jylrq5Ot87mzZuViy++WPF4PErfvn2Vxx9//Fy9xLPO6vwBUF588UVtnaamJuWb3/ymkpeXp6SnpyvXX3+9cuzYMd1+Dh48qFx11VVKWlqaUlBQoHz3u99VAoGAbp33339fmTBhguJ2u5XBgwfrnqOz+/rXv64MGDBAcbvdSs+ePZUZM2ZoFxtF4TlsC+NFh+ey4+G1KYrXpdTgtSk1eG06OzrydUlSFEVJLpdERERERETU+XXZMUNERERERESxMBgiIiIiIqJuicEQERERERF1SwyGiIiIiIioW2IwRERERERE3RKDISIiIiIi6pYYDBERERERUbfEYIiIiIiIiLolBkNEKXLbbbfhuuuua+/DICIiAsDrElEiGAwREREREVG3xGCIKEmvvvoqxo4di7S0NPTo0QMzZ87E/fffjz/96U946623IEkSJElCeXk5AODw4cP4r//6L+Tm5iI/Px/XXnstDh48qO1P/ebu4YcfRs+ePZGdnY27774bfr+/fV4gERF1KrwuEbWes70PgKgzOXbsGObOnYsnnngC119/Perq6vDBBx/glltuQUVFBWpra/Hiiy8CAPLz8xEIBDBr1iyUlpbigw8+gNPpxE9/+lNceeWV2LJlC9xuNwBg5cqV8Hq9KC8vx8GDBzFv3jz06NEDP/vZz9rz5RIRUQfH6xJR2zAYIkrCsWPHEAwGccMNN2DAgAEAgLFjxwIA0tLS4PP5UFRUpK3/l7/8BeFwGM8//zwkSQIAvPjii8jNzUV5eTmuuOIKAIDb7cYLL7yA9PR0jB49Go888gjuv/9+PProo5BlJnCJiMgar0tEbcN3M1ESxo8fjxkzZmDs2LH4z//8Tzz33HOorq62XX/z5s3Yu3cvsrKykJmZiczMTOTn56O5uRn79u3T7Tc9PV37ubS0FPX19Th8+PBZfT1ERNS58bpE1DbMDBElweFwoKysDB9//DFWrFiB3/72t/jRj36EdevWWa5fX1+PkpIS/PWvfzU91rNnz7N9uERE1MXxukTUNgyGiJIkSRKmTp2KqVOnYvHixRgwYADeeOMNuN1uhEIh3boTJ07EK6+8gl69eiE7O9t2n5s3b0ZTUxPS0tIAAGvXrkVmZiaKi4vP6mshIqLOj9clotZjmRxREtatW4fHHnsMn376KSoqKvD666/jxIkTGDlyJAYOHIgtW7Zg9+7dOHnyJAKBAG6++WYUFBTg2muvxQcffIADBw6gvLwc9957L44cOaLt1+/34/bbb8eOHTuwbNkyPPjgg1iwYAHrsomIKCZel4jahpkhoiRkZ2dj9erVeOqpp1BbW4sBAwbgl7/8Ja666ipMmjQJ5eXlmDRpEurr6/H+++/j0ksvxerVq/HAAw/ghhtuQF1dHfr27YsZM2bovpGbMWMGhg0bhunTp8Pn82Hu3Ll46KGH2u+FEhFRp8DrElHbSIqiKO19EETd2W233YYzZ87gzTffbO9DISIi4nWJuhXmOomIiIiIqFtiMERERERERN0Sy+SIiIiIiKhbYmaIiIiIiIi6JQZDRERERETULTEYIiIiIiKibonBEBERERERdUsMhoiIiIiIqFtiMERERERERN0SgyEiIiIiIuqWGAwREREREVG3xGCIiIiIiIi6pf8Pd8V27u5BwakAAAAASUVORK5CYII="
     },
     "metadata": {}
    }
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 评估"
   ],
   "metadata": {}
  },
  {
   "cell_type": "code",
   "source": [
    "# dataload for evaluating\n",
    "\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(\"checkpoints/imdb-lstm/best.ckpt\", map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, test_dl, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ],
   "metadata": {
    "execution": {
     "iopub.status.busy": "2024-05-03T04:53:30.082914Z",
     "iopub.execute_input": "2024-05-03T04:53:30.083787Z",
     "iopub.status.idle": "2024-05-03T04:53:37.545678Z",
     "shell.execute_reply.started": "2024-05-03T04:53:30.083748Z",
     "shell.execute_reply": "2024-05-03T04:53:37.544622Z"
    },
    "trusted": true
   },
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "text": "loss:     0.3217\naccuracy: 0.8768\n",
     "output_type": "stream"
    }
   ]
  }
 ]
}
